Материал: Мансуров. Основы программирования в среде Lazarus. 2010

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

if (srNode.Attr and faDirectory) <> 0 then begin

DirName:= ListView1.Selected.Caption;

Show_ListView_Dir(DirName);

Show_ListView_Files(DirName);

exit;

end;

if (srNode.Attr and faHidden) = 0 then begin

progr:= pchar(s); {$IFDEF UNIX}

shell(progr);

{$ELSE}

WinExec(progr, 1);

{$ENDIF} end;

end;

В Linux при таком способе запуска исполняемого файла запустить кон-

сольное приложение не удастся, поскольку консольное приложение должно за-

пускаться в консоли или терминале. Кроме того, существует более эффектив-

ный способ запуска внешних приложений, подходящий как для Linux, так и для

Windows. Это использование процессов и потоков (нитей). Не вдаваясь в под-

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

Создать и запустить дочерний процесс можно следующим образом:

var

AProcess: TProcess;

701

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

begin

AProcess:= TProcess.Create(nil);

AProcess.CommandLine:= 'Имя исполняемого файла';

AProcess.Execute;

AProcess.Free;

end;

Перепишем обработчик OnDblClick:

procedure TForm1.ListView1DblClick(Sender: TObject); var

s: string; AProcess: TProcess; srNode: TSearchRec; DirName: string;

begin

if ListView1.Selected = nil then exit; {$IFDEF WINDOWS}

s:= path + UTF8ToSys(ListView1.Selected.Caption); {$ELSE}

s:= path + ListView1.Selected.Caption; {$ENDIF}

if FindFirst(s, faAnyFile, srNode) = 0 then if (srNode.Attr and faDirectory) <> 0 then begin

DirName:= ListView1.Selected.Caption;

Show_ListView_Dir(DirName);

Show_ListView_Files(DirName);

exit;

702

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

end;

if (srNode.Attr and faHidden) = 0 then begin

AProcess:= TProcess.Create(nil);

{$IFDEF UNIX}

if MessageDlg('Открывать в терминале?', mtCustom, [mbYes, mbNO], 0) = mrYes then

s:= 'xterm -T ''Lazarus Run Output''' + ' -e $(TargetCmdLine)' + s;

{$ENDIF} AProcess.CommandLine:= s; AProcess.Execute; AProcess.Free;

end;

end;

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

цедура решает свою задачу. Я имею в виду, что в них имеются повторяющиеся участки кода. Хотелось бы написать одну общую процедуру. Ясно, что эта

"универсальная" процедура будет довольно-таки запутанной из-за необходимо-

сти производить многочисленные проверки. В таких случаях перед программи-

стом всегда встает дилемма, что выбрать – простой и ясный код, но с дублиро-

ванием или код "с наворотами".

Все же большинство профессиональных программистов предпочтут более про-

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

фицировать. Ведь спустя некоторое время разбираться даже в своей собствен-

ной программе бывает достаточно тяжело.

703

6.3 Визуальное программирование в среде Lazarus

____________________________________________________________________

Однако мы все же попробуем объединить эти пять процедур в одну. Назо-

вем эту процедуру ShowExpandNode и введем два дополнительных параметра

ShowMode: integer и IsinTListView: boolean.

Пусть ShowMode = 0, если необходимо вывести каталоги в TTreeView.

ShowMode = 1, если необходимо вывести только каталоги в

TListView, но узел берется из TTreeView.

ShowMode = 2, если необходимо вывести только файлы в TListView

из каталога выбранного в TTreeView.

IsinTListView = false, если мы находимся в TTreeView.

IsinTListView = true, если мы находимся в TListView.

Окончательно код программы будет выглядеть следующим образом:

unit Unit1;

{$mode objfpc}{$H+} interface

uses

Classes, SysUtils, FileUtil, LResources, Forms,

Controls, Graphics, Dialogs, ComCtrls, StdCtrls,

ExtCtrls, LCLType, Process,

{$IFDEF UNIX}

unix;

{$ELSE}

Windows;

{$ENDIF} type

{ TForm1 }

TForm1 = class(TForm)

704

Глава 6 Программирование приложений с графическим интерфейсом

____________________________________________________________________

ImageList1: TImageList;

ListView1: TListView;

Memo1: TMemo;

TreeView1: TTreeView;

procedure FormCreate(Sender: TObject); procedure ListView1DblClick(Sender: TObject); procedure TreeView1Change(Sender: TObject; Node:

TTreeNode); procedure TreeView1Expanding(Sender: TObject;

Node: TTreeNode; var AllowExpansion: Boolean); function Real_Directory(sname: string): boolean; procedure ShowExpandNode(ParentNode: TTreeNode;

DirName: string; ShowMode: integer;

IsinTListView: boolean);

function GetPath(ParentNode: TTreeNode): string; function GetPath_1(DirName: string;

p: string): string;

{$IFDEF WINDOWS}

function Find_Logical_Disks(): boolean; procedure SetAllDirectories;

{$ENDIF} private

{private declarations } public

{public declarations } end;

var

Form1: TForm1;

path, oldpath: string;

705

Смотрите также:

11 Горм +
113
14
1433
1511
1632
199
204
2N4264RE
3773