Вывод диалога для выбора каталога

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Разговаривают два юзера.

— Я слышал, что если проиграть CD-ROM c Виндоуз 2000 в обратную сторону, то получится послание от сатаны!

— Куда страшней другое: если ты проиграешь его как надо, то инсталлируется Виндоуз 2000…

uses

ShellAPI, ShlObj;

procedure TForm1.Button1Click(Sender: TObject);

var

TitleName : string;

lpItemID : PItemIDList;

BrowseInfo : TBrowseInfo;

DisplayName : array[0..MAX_PATH] of char;

TempPath : array[0..MAX_PATH] of char;

begin

FillChar(BrowseInfo, sizeof(TBrowseInfo), #0);

BrowseInfo.hwndOwner := Form1.Handle;

BrowseInfo.pszDisplayName := @DisplayName;

TitleName := ‘Please specify a directory’;

BrowseInfo.lpszTitle := PChar(TitleName);

BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS;

lpItemID := SHBrowseForFolder(BrowseInfo);

if lpItemId nil then

begin

SHGetPathFromIDList(lpItemID, TempPath);

ShowMessage(TempPath);

GlobalFreePtr(lpItemID);

end;

end;

{/codecitation}

Вывести все файлы директории

[cc lang=»delphi»]
procedure ListFileDir(Path: string; FileList: TStrings);

var

SR: TSearchRec;

begin

if FindFirst(Path ‘*.*’, faAnyFile, SR) = 0 then

begin

repeat

if (SR.Attr faDirectory) then

begin

FileList.Add(SR.Name);

end;

until FindNext(SR) 0;

FindClose(SR);

end;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

ListFileDir(‘C:\WINDOWS\’, ListBox1.Items);

end;
[/cc]

Автоматическое получение следующего имени файла в каталоге

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Автор: Igor Kovalevsky

WEB-сайт: http://delphibase.endimus.com

{ **** UBPFD *********** by delphibase.endimus.com ****

>> Автоматическое получение следующего имени файла в каталоге

Функция предоставляет Вам каждый раз новое имя файла,

а если список файлов исчерпан, начинает перебор снова.

Может пригодиться при написании Вашего собственного

слайдшоу с фотографиями или в похожих задачах, где

важно не повторить до конца списка уже воспроизведённый файл.

Зависимости: Windows, Messages, SysUtils, Classes, DIALOGS;

Автор: Igor Kovalevsky, pc-ambulance@mail.ru, Владикавказ

Copyright: Igor Kovalevsky

Дата: 1 июня 2002 г.

***************************************************** }

function GetNextFileName(Path: string): string;

const

ListFileName = ‘ListFile.lst’;

FileMask = ‘*.*’

var

SearchRec: TSearchRec;

begin

with TStringList.Create do

begin

if FileExists(ListFileName) then

begin

LoadFromFile(ListFileName);

end;

if FindFirst(IncludeTrailingBackslash(Path) FileMask,

faAnyFile and not faDirectory,

SearchRec) = 0 then

begin

// Редкий случай, когда цикл repeat..until

// на что-то годится

repeat

Result := SearchRec.Name;

if (FindNext(SearchRec) 0) then

begin

Clear;

end;

until (IndexOf(Result) = -1);

Add(Result);

FindClose(SearchRec);

end

else

begin

Result := »;

end;

SaveToFile(ListFileName);

Free;

end;

end;

Пример использования:

ShowMessage(GetNextFileName(‘C:\Windows\’));

{/codecitation}

TreeView каталогов — как в левой части проводника

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Автор: Даниил Карапетян

WEB сайт: http://program.dax.ru

Когда ваш компьютер говорит «Вставьте диск #2», не торопитесь, сначала выньте диск номер один… даже если вы уверены, что сможете засунуть туда оба.

Самый простой способ — это при запуске программы найти все каталоги на диске и засунуть их в TreeView. Но у этого способа есть несколько недостатков. Во-первых, он долгий, особенно, если включен zif. Во-вторых, даже если закрыть и открыть какую-то папку, она не обновится. Поэтому лучше всего вначале сделать в TreeView список дисков со значком » «, то есть указать, что на диске есть каталоги. Это не всегда верно, но проверять, правда ли это, долго из-за дисковода. При попытке раскрыть каталог или диск программа ищет подкаталоги и добавляет их в ListView. В каждом подкаталоге программа пытается найти хотя бы один подкаталог. В зависимости от результатов поиска » » появляется или нет. В этой программе используются иконки из файла FileCtrl.res, находящемся в каталоге «Delphi5\lib».

implementation

{$R *.DFM}

{$R FileCtrl}

procedure NextLevel(ParentNode: TTreeNode);

function DirectoryName(name: string): boolean;

begin

result := (name > ‘.’) and (name > ‘..’);

end;

var

sr, srChild: TSearchRec;

node: TTreeNode;

path: string;

begin

node := ParentNode;

path := »;

repeat

path := node.Text ‘\’ path;

node := node.Parent;

until

node = nil;

if FindFirst(path ‘*.*’, faDirectory, sr) = 0 then

begin

repeat

if (sr.Attr and faDirectory > 0) and DirectoryName(sr.name) then

begin

node := Form1.TreeView1.Items.AddChild(ParentNode, sr.name);

node.ImageIndex := 0;

node.SelectedIndex := 1;

node.HasChildren := false;

if FindFirst(path sr.name ‘\*.*’, faDirectory, srChild) = 0 then

begin

repeat

if (srChild.Attr and faDirectory > 0) and

DirectoryName(srChild.name) then

node.HasChildren := true;

until

(FindNext(srChild) > 0) or node.HasChildren;

end;

FindClose(srChild);

end;

until

FindNext(sr) > 0;

end

else

ParentNode.HasChildren := false;

FindClose(sr);

end;

procedure TForm1.FormCreate(Sender: TObject);

const

IconNames: array [0..6] of string = (‘CLOSEDFOLDER’, ‘OPENFOLDER’,

‘FLOPPY’, ‘HARD’, ‘NETWORK’, ‘CDROM’, ‘RAM’);

var

c: char;

s: string;

node: TTreeNode;

DriveType: integer;

bm, mask: TBitmap;

i: integer;

begin

TreeView1.Items.BeginUpdate;

TreeView1.Images := TImageList.CreateSize(16, 16);

bm := TBitmap.Create;

mask := TBitmap.Create;

for i := low(IconNames) to high(IconNames) do

begin

bm.Handle := LoadBitmap(HInstance, PChar(IconNames[i]));

bm.Width := 16;

bm.Height := 16;

mask.Assign(bm);

mask.Mask(clBlue);

TreeView1.Images.Add(bm, mask);

end;

for c := ‘A’ to ‘Z’ do

begin

s := c ‘:’;

DriveType := GetDriveType(PChar(s));

if DriveType = 1 then

continue;

node := Form1.TreeView1.Items.AddChild(nil, s);

case DriveType of

DRIVE_REMOVABLE: node.ImageIndex := 2;

DRIVE_FIXED: node.ImageIndex := 3;

DRIVE_REMOTE: node.ImageIndex := 4;

DRIVE_CDROM: node.ImageIndex := 5;

else

node.ImageIndex := 6;

end;

node.SelectedIndex := node.ImageIndex;

node.HasChildren := true;

end;

TreeView1.Items.EndUpdate;

end;

procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;

var AllowExpansion: Boolean);

begin

TreeView1.Items.BeginUpdate;

node.DeleteChildren;

NextLevel(node);

TreeView1.Items.EndUpdate;

end;

{/codecitation}

Cколько файлов есть в определённой папке

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Автор: Vit

WEB-сайт: http://forum.vingrad.ru

function GetFileCount(Dir: string): integer;

var

fs: TSearchRec;

begin

Result := 0;

if FindFirst(Dir ‘\*.htm’, faAnyFile — faDirectory — faVolumeID, fs) = 0

then

repeat

inc(Result);

until

FindNext(fs) 0;

FindClose(fs);

end;

{/codecitation}

Создание Аккаунта в Windows, используя ADSI (Активные директории)

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Встречаются два программиста. Первый: — Слушай, одкуда у тебя такой классный велик?- — Да не поверишь. Сижу вчера на берегу, обдумываю новую программу, тут подъезжает ко мне такая красивая девушка на велосипеде, снимает с себя все и говорит:»Бери все, что хочешь.». Ну, я и взял велосипед, а на хрена мне ее одежда?.

Чтобы создавать пользовательские аккаунты в Windows на Delphi можно использовать ADSI (Active Directory Services Interface) от Microsoft. Вы думаете, что ADSI это новая примочка для Windows 2000 (судя по названию) , но оказывается ADSI доступна для всех платформ Win32. Для этого Вам потребуется всего навсего скачать ADSI для Windows (более полная информация на http://www.microsoft.com/adsi ). Ну и конечно же ADSI входит в поставку Windows 2000.

ADSI довольно большой предмет для изучения. В данном примере я затрону этот предмет поверхностно. ADSI — это своего рода основа для различных сервисов (обычно основанных на директориях) оперционной системы. Например, стандартными ADSI сервисами можно назвать (COM интерфейсы, которые можно использовать в программах) WinNT, IIS, LDAP и NDS. WinNT сервис может тем самым использоваться для создания пользовательских аккаунтов, модификации их или модификации групп.

Следующий небольшой пример показывает необходимые шаги для создания пользовательского аккаунта в NT/2000, используя ADSI:

Во первых Вам прийдётся импортировать Библиотеку Типов ADSI (Menu Project/Import Type Library). Библиотеку Типов можно найти в поддирректории system32 (Например C:\WINNT\system32\activeds.tlb). Требуемый файл называется ‘activeds.tlb’. Если такого файла нет, то проверьте, правильно ли вы установили ADSI. После успешного импортирования Библиотеки Типов Вы найдёте новый файл в дирректории ипортов Delphi, файл будет называться «activeds_tlb.pas» (..\Delphi5\Imports\activeds_tlb.pas). Чтобы приступить к программированию ADSI в Delphi, необходимо включить этот файл в Ваш проект.

Далее в примере, необходимо заменить [computername] на фактическое имя компьютера, с которым Вы работаете. То же надо проделать с [accountname]. Пример тестировался на WindowsNT 4.0 и Windows 2000.

uses ActiveX, // используется для COM Moniker stuff…

ActiveDs_TLB, // созданная библиотека типов

ComObj; // используется для OleCheck и других функций COM

implementation

procedure TForm1.BtnCreateUserClick(Sender: TObject);

var

Usr: IADsUser;

Comp: IADsContainer;

begin

try

Comp := GetObject(‘WinNT://[computername],computer’) as IADsContainer;

Usr := Comp.Create(‘user’, ‘[accountname]’) as IADsUser;

Usr.SetInfo;

except

on E: EOleException do

begin

ShowMessage(E.message);

end;

end;

end;

procedure TForm1.BtnSetPasswordClick(Sender: TObject);

var

Usr: IADsUser;

begin

try

Usr := GetObject(‘WinNT://[computername]/[accountname],user’) as IADsUser;

Usr.SetPassword(‘thenewpassword’);

except

on E: EOleException do

begin

ShowMessage(E.message);

end;

end;

end;

// GetObject использует вызов VB GetObject

// Данный код (GetObject) был найден в Usenet.

// GetObject позволяет связаться с существующим ADSI сервисом

// используя ‘ADSIPath’ (например WinNT://…. или

// IIS://localhost).

function TForm1.GetObject(const name: string): IDispatch;

var

Moniker: IMoniker;

Eaten: integer;

BindContext: IBindCtx;

Dispatch: IDispatch;

begin

OleCheck(CreateBindCtx(0, BindContext));

OleCheck(MkParseDisplayName(BindContext, PWideChar(WideString(name)), Eaten, Moniker));

OleCheck(Moniker.BindToObject(BindContext, nil, IDispatch, Dispatch));

Result := Dispatch;

end;

end.

Через ADSI Вы так же можете изменять параметры пользовательских аккаунтов. Следующий код изменяет флаг ‘Password never expires’ нужного аккаунта:

procedure TFormMain.ButtonNeverExpiresClick(Sender: TObject);

var

Usr: IADsUser;

begin

try

Usr := GetObject(‘WinNT://[computername]/[acccoutname],user’) as IADsUser;

// Проверяем состояние чекбоксов…

if CheckBoxPasswordNeverExpires.Checked then

Usr.Put(‘UserFlags’, Usr.Get(‘UserFlags’) or 65536)

// 65536 объявлено как UF_DONT_EXPIRE_PASSWORD в iads.h

// в ADSI SDK от Microsoft

else

Usr.Put(‘UserFlags’, Usr.Get(‘UserFlags’) xor 65536);

Usr.SetInfo;

except

on E: EOleException do

begin

ShowMessage(E.message);

end;

end;

end;

В завершении…

Чтобы использовать большие возможности ADSI , необходимо проверить, поддерживаются ли такие сервисы как IADsUser или IADsContainer.

Я рекомендую поработать с ADSI SDK от Microsoft и более детально изучить Библиотеку Типов.

Некоторые ADSI компоненты я постараюсь выложить на своей домашней страничке http://www.jespersen.ch. Так что, если интересно, то заходите и мыльте на philip@jespersen.ch

{/codecitation}

Компонент для последовательного устройства (TRS232)

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Просыпается программист с большого бодуна, поворачивается, а рядом какая-то девушка лежит.

— Ooрs, обнаружено новое устройство…

Компонент, который представлен здесь, выполняет функции синхронного чтения и записи в последовательный интерфейс RS232.

В цикле выполняется Application.ProcessMessages, чтобы все сообщения от основной программы обрабатывались.

Ниже приведён метод ReadString из компонента TRS323:

function TRS232.ReadString(var aResStr: string; aCount: word ): boolean;

var

nRead: dword;

Buffer: string;

Actual, Before: TDateTime;

TimeOutMin, TimeOutSec, lCount: word;

begin

Result := false;

if not Connected then

if not Connect then

raise Exception.CreateHelp(‘RS232.ReadString:’

‘ Connect not possible !’, 101);

aResStr := »;

TimeOutMin:=TimeOut div 60;

TimeOutSec:=TimeOut mod 60;

if (not Connected) or (aCount <= 0) then

EXIT;

nRead := 0; lCount := 0;

Before := Time;

while lCount < ACOUNT do

begin

Application.ProcessMessages;

SetLength(Buffer,1);

if ReadFile( FComPortHandle, PChar(Buffer)^, 1, nRead, nil) then

begin

if nRead > 0 then

begin

aResStr := aResStr Buffer;

inc(lCount);

end;

Actual := Time;

if Actual-Before>EncodeTime(0, TimeOutMin, TimeOutSec, 0) then

raise Exception.CreateHelp(‘RS232.ReadString: TimeOut !’, 103);

end

else

begin

raise Exception.CreateHelp(‘RS232.ReadString: Read not possible !’, 104);

end;

end;

Result:=true;

end;

{/codecitation}

Как узнать, есть ли в приёмном буфере RS232 данные

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Телепрограмма на сегодня:

4.00 РОWЕRхностные явления.

4.05 Winсиканский сериал — «Lоаding in рrоgrеss» 10-11 проценты.

8.30 Игра на мониторе — «Угадай меLОАDию» Yеs,Nо,Саnсеl.

9.00 Программа «Доброе утро, Мustdай».

9.30 «Сам себе Панель Мiсrоsоft Оffiсе».

10.00 Веселые SТАRТы.

11.00 Мультик «Кто сказал БИЗИ?».

11.10 «Соnnесt с первого взгляда».

11.30 «Утренняя почта» с Г. Олдедом.

12.00 NоСаrriеrчко.

12.30 Аdоbе МозгоЕb. В перерывах СкринSаvеrы.

14.00 Самая криминальная программа на мониторе: «Недопустимая операция. Закрыть. Сведения.».

14.30 Юмор на мониторе — клуб «Белый Rеsеt».

15.00-19.00 Профилактические работы. Сериал «SсаnDisk».

19.45 Для самых маленьких — «Unаblе Еrrоr, малыши!».

20.00 Документальные данные о реестре «ИеRАRхическая поDLLость».

20.30 Юмористический мониторожурнал — «Назло DirесtХ».

22.00 Ночной сеанс — «Установка и удаление программ». В главной роли UnInstаll Windоws’98.

23.00 Как это было. «Windоws 3.11» 1990 год.

00.00 Контра, Альт, Дель.

При помощи функции ClearCommError можно узнать, сколько байт данных находится в буфере приёма (и буфере передачи) последовательного интерфейса.

procedure DataInBuffer(Handle: THandle;

var InQueue, OutQueue: integer);

var

ComStat: TComStat;

e: integer;

begin

if ClearCommError(Handle, e, @ComStat) then

begin

InQueue := ComStat.cbInQue;

OutQueue := ComStat.cbOutQue;

end

else

begin

InQueue := 0;

OutQueue := 0;

end;

end;

{/codecitation}

Работа с INI-файлами

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Оформил: DeeCo

Автор: http://www.swissdelphicenter.ch

{

An INI file stores information in logical groupings, called “sections.”

Within each section, actual data values are stored in named keys.

[Section_Name]

Key_Name1=Value1

Key_Name2=Value2

}

uses

IniFiles;

// Write values to a INI file

procedure TForm1.Button1Click(Sender: TObject);

var

ini: TIniFile;

begin

// Create INI Object and open or create file test.ini

ini := TIniFile.Create(‘c:\MyIni.ini’);

try

// Write a string value to the INI file.

ini.WriteString(‘Section_Name’, ‘Key_Name’, ‘String Value’);

// Write a integer value to the INI file.

ini.WriteInteger(‘Section_Name’, ‘Key_Name’, 2002);

// Write a boolean value to the INI file.

ini.WriteBool(‘Section_Name’, ‘Key_Name’, True);

finally

ini.Free;

end;

end;

// Read values from an INI file

procedure TForm1.Button2Click(Sender: TObject);

var

ini: TIniFile;

res: string;

begin

// Create INI Object and open or create file test.ini

ini := TIniFile.Create(‘c:\MyIni.ini’);

try

res := ini.ReadString(‘Section_Name’, ‘Key_Name’, ‘default value’);

MessageDlg(‘Value of Section: ‘ res, mtInformation, [mbOK], 0);

finally

ini.Free;

end;

end;

// Read all sections

procedure TForm1.Button3Click(Sender: TObject);

var

ini: TIniFile;

begin

ListBox1.Clear;

ini := TIniFile.Create(‘MyIni.ini’);

try

ini.ReadSections(listBox1.Items);

finally

ini.Free;

end;

end;

// Read a section

procedure TForm1.Button4Click(Sender: TObject);

var

ini: TIniFile;

begin

ini: = TIniFile.Create(‘WIN.INI’);

try

ini.ReadSection(‘Desktop’, ListBox1.Items);

finally

ini.Free;

end;

end;

// Read section values

procedure TForm1.Button5Click(Sender: TObject);

var

ini: TIniFile;

begin

ini := TIniFile.Create(‘WIN.INI’);

try

ini.ReadSectionValues(‘Desktop’, ListBox1.Items);

finally

ini.Free;

end;

end;

// Erase a section

procedure TForm1.Button6Click(Sender: TObject);

var

ini: TIniFile;

begin

ini := TIniFile.Create(‘MyIni.ini’);

try

ini.EraseSection(‘My_Section’);

finally

ini.Free;

end;

end;

{/codecitation}

Работа с INI файлами

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Автор: Михаил Христосенко

WEB сайт: http://mihandelphi.narod.ru

В этой статье мы рассмотрим технику создания инифайлов их назначение и применение. Начнем с ответа на вопрос зачем же нужны эти инифайлы?! Предположим, что вы создали приложение, в котором пользователь может настраивать цвет фона, шрифт надписей и так далее. Когда он повторно включит вашу программу он очень сильно разочаруется, так как всего его старания по настройке интерфейса вашей программы пропали даром — программа будет иметь такой вид, который сделали вы при проектировании программы. Так вот чтобы эти настройки сохранять, лучше всего пользоваться инифайлами.

Одно из главных преимуществ инифайлов заключается в том, что эти файлы подерживают переменные разных типов (String, Integer, Boolean). В этих файлах очень удобно хранить различные настройки, например параметры шрифта, цвет фона, какие checkbox’ы выбрал пользователь и многое другое.

Теперь начнем разбираться с этими инифайлами. Для начала создайте новое приложение. Добавьте в секцию uses слово inifiles. Сохраните и откомпилируйте ваше приложение. Теперь сделаем, чтобы при каждом открытии программы форма имела такие размеры, какие установил пользователь последний раз. Для начала нам надо создать объект типа Inifile. Создается он методом Create(Filename:string); причем если в переменной Filename не указан путь к фалу, то он создаться в директории Windows, что не очень-то удобно. Поэтому мы создадим этот файл в директории нашей программы. Напишем это в обработчик события OnDestroy для формы:

procedure TForm1.FormDestroy(Sender: TObject);

var

Ini: Tinifile; //необходимо создать объект, чтоб потом с ним работать

begin

//создали файл в директории программы

Ini:=TiniFile.Create(extractfilepath(paramstr(0)) ‘MyIni.ini’);

Ini.WriteInteger(‘Size’,’Width’,form1.width);

Ini.WriteInteger(‘Size’,’Height’,form1.height);

Ini.WriteInteger(‘Position’,’X’,form1.left);

Ini.WriteInteger(‘Position’,’Y’,form1.top);

Ini.Free;

end;

Если файл с таким именем существует, то он откроется для чтения, а если нет — то он будет создан. Это очень удобно, так как не надо обрабатывать возможные исключительные ситуации, которые могут возникнуть при обращении к файлу.

Вот файл MyIni.ini после завершения работы программы (у вас естественно значения будут другими):

[Size]

Width=188

Height=144

[Position]

X=14

Y=427

Теперь подробно разберемся как записывать информацию в инифайлы: После того, как вы создали инифайл, в него можно записывать три вида переменных: Integer, String, Boolean, это осуществляется соответствующими процедурами: WriteInteger, WriteString, WriteBool. У всех этих процедур одинаковые параметры. В общем объявление этих процедур выглядит так:

Ini.WriteInteger(const Section: string, const Ident:string, Value: Integer);

Здесь Section -это имя секции, куда будут помещены параметры и значения. В файле имена секций заключены в квадратные скобки. Обычно в секции объединяют схожие параметры.

Ident — это название параметра, которому будет присваиваться какое-нибудь значение.

Value — это собственно значение, которое будет присвоено параметру. В файле оно стоит после знака равно.

Теперь напишем обработчик события OnCreate для формы, в котором будем считывать значения из файла и изменять размеры формы в соответствии с полученными значениями. Код должен иметь такой вид:

procedure TForm1.FormCreate(Sender: TObject);

var

Ini: Tinifile;

begin

//открываем файл

Ini:=TiniFile.Create(extractfilepath(paramstr(0)) ‘MyIni.ini’);

Form1.Width:=Ini.ReadInteger(‘Size’,’Width’,100);

//последнее значение (100) это значение по умолчанию (default)

Form1.Height:=Ini.ReadInteger(‘Size’,’Height’,100);

Form1.Left:=Ini.ReadInteger(‘Position’,’X’,10);

Form1.Top:=Ini.WriteInteger(‘Position’,’Y’,10);

Ini.Free;

end;

В этом коде все просто: открыли файл, прочитали из соответствующих секций необходимые параметры и присвоили их форме. Чтение значений из инифайла по сути ничем не отличается от записи в них. Указываете секцию, где хранится необходимый параметр, указываете параметр и читаете его значение. Как вы видите все просто!

Теперь я отвечу еще на один вопрос, который может появиться — почему не обычные текстовые файлы и не реестр? Отвечаю: из текстового файла очень сложно получить и обработать необходимую информацию. Многие рекомендуют для Win95/98/2000/Me, короче для всех 32-разрядных ОС использовать именно реестр, но лично я считаю, что инифайлы удобнее, так как при при переносе программы на другой компьютер, нужно перенести только один инифайл, а во-вторых, если вы что-нибудь в реестре случайно удалите, то может случиться каюк.

{/codecitation}