Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лабораторные на Pasca (Кудрявцев)l

.pdf
Скачиваний:
32
Добавлен:
18.03.2015
Размер:
1.63 Mб
Скачать

Диалоговые окна

313

 

 

В заключение приведем окончательный текст программы TFirst6 со всеми внесенными в нее изменениями.

Program TFirst6;

uses App, Objects, Menus, Drivers, Views, Dialogs; const

FileToRead='e:\tp60\urok.txt'; MaxLines = 100; cmNewWin=199; cmFileOpen=200; cmNewDialog = 201; winCount: Integer = 0;

type TMyApp=Object(TApplication) procedure InitStatusLine; virtual; procedure InitMenuBar; virtual; procedure NewWindow; virtual; procedure NewDialog;

procedure HandleEvent(var Event: TEvent); virtual; end;

type PInterior=^Tinterior;

TInterior=object(TScroller)

constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);

procedure Draw; virtual; end;

type PDemoWindow=^TDemoWindow; TDemoWindow=object(TWindow)

constructor Init(Bounds: TRect; WinTitle: string; WindowNo: Integer);

function MakeInterior(Bounds: TRect; Left: Boolean): PInterior; procedure SizeLimits(var Min,Max:TPoint);virtual;

end; type

PDemoDialog = ^TDemoDialog; TDemoDialog = object(TDialog) end;

type

DialogData = record CheckBoxData: Word;

314

Лабораторная работа № 27

 

 

RadioButtonData: Word; InputLineData: string[128];

end; var

MyApp: TMyApp; S: string; LineCount: Integer;

Lines: array[0..MaxLines - 1] of PString; DemoDialogData: DialogData;

procedure TDemoWindow.SizeLimits(var Min,Max:TPoint); var R: TRect;

begin TWindow.SizeLimits(Min,Max); GetExtent(R);

Min.X:=R.B.X div 2; end;

constructor TInterior.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);

begin

TScroller.Init(Bounds, AHScrollBar, AVScrollBar); Options := Options or ofFramed;

SetLimit(128, LineCount); end;

procedure ReadFile; var

F: Text;

S: String; begin LineCount := 0;

Assign(F,FileToRead);

Reset(F);

while not Eof(F) and (LineCount < MaxLines) do begin

Readln(F, S); Lines[LineCount] := NewStr(S); Inc(LineCount);

end;

Close(F);

end;

procedure DoneFile; var

I: Integer;

Диалоговые окна

315

 

 

begin

for I := 0 to LineCount - 1 do

if Lines[I] <> nil then DisposeStr(Lines[i]); end;

procedure TInterior.Draw; var

Color: Byte;

I,Y: Integer;

B: TDrawBuffer; begin

Color := GetColor(1);

for Y := 0 to Size.Y - 1 do begin

MoveChar(B, ' ', Color, Size.X); i := Delta.Y + Y;

if (I < LineCount) and (Lines[I] <> nil) then

MoveStr(B, Copy(Lines[I]^, Delta.X + 1, Size.X), Color); WriteLine(0, Y, Size.X, 1, B);

end;

end;

constructor TDemoWindow.Init(Bounds: TRect; WinTitle: string; WindowNo: Integer);

var

S: string[3]; R: TRect;

RInterior, LInterior: PInterior; begin

Str(WindowNo, S);

TWindow.Init(Bounds, WinTitle+' '+S, wnNoNumber); GetExtent(Bounds);

R.Assign(Bounds.A.X, Bounds.A.Y, Bounds.B.X div 2 + 1, Bounds.B.Y); LInterior := MakeInterior(R, True);

LInterior^.GrowMode := gfGrowHiY; Insert(Linterior);

R.Assign(Bounds.B.X div 2, Bounds.A.Y, Bounds.B.X, Bounds.B.Y); RInterior := MakeInterior(R,False);

RInterior^.GrowMode := gfGrowHiX + gfGrowHiY; Insert(RInterior);

end;

function TDemoWindow.MakeInterior(Bounds: TRect; Left: Boolean): PInterior;

var

316

Лабораторная работа № 27

 

 

HScrollBar, VScrollBar: PScrollBar; R: TRect;

begin

R.Assign(Bounds.B.X-1, Bounds.A.Y+1, Bounds.B.X, Bounds.B.Y-1); VScrollBar := New(PScrollBar, Init(R));

VScrollBar^.Options := VScrollBar^.Options or ofPostProcess; if Left then VScrollBar^.GrowMode := gfGrowHiY; Insert(VScrollBar);

R.Assign(Bounds.A.X+2, Bounds.B.Y-1, Bounds.B.X-2, Bounds.B.Y); HScrollBar := New(PScrollBar, Init(R));

HScrollBar^.Options := HScrollBar^.Options or ofPostProcess; if Left then HScrollBar^.GrowMode := gfGrowHiY + gfGrowLoY; Insert(HScrollBar);

Bounds.Grow(-1,-1);

MakeInterior := New(PInterior, Init(Bounds, HScrollBar, VScrollBar)); end;

procedure TMyApp.InitStatusLine; var R:TRect;

begin GetExtent(R); R.A.Y:=R.B.Y-1;

StatusLine:=New(PStatusLine,Init(R, NewStatusDef(0,$FFFF, NewStatusKey('~Alt-X~Exit',kbAltX,cmQuit, NewStatusKey('~F4~New',kbF4,cmNewWin, NewStatusKey('~Alt-F3~Close',kbAltF3,cmClose, NewStatusKey('~F10~Menu',kbF10,cmMenu,

nil)))),

nil)))

end;

procedure TMyApp.InitMenuBar; var R:TRect;

begin GetExtent(R); R.B.Y:=R.A.Y+1;

MenuBar:=New(PMenuBar,Init(R,NewMenu(

NewSubMenu('~F~ile',hcNoContext,NewMenu(

NewItem('~O~pen','F3',kbF3,cmFileOpen,

hcNoContext,

NewItem('~N~ew','F4',kbF4,cmNewWin,

hcNoContext,

NewLine(

Диалоговые окна

317

 

 

NewItem('E~x~it','Alt-X',kbAltX,cmQuit, hcNoContext,

nil))))),

NewSubMenu('~W~indow',hcNoContext,NewMenu(

NewItem('~N~ext','F6',kbF6,cmNext,

hcNoContext,

NewItem('~Z~oom','F5',kbF5,cmZoom,

hcNoContext, NewItem('~S~ize/Move','Ctr-F5',kbCtrlF5,cmResize,

hcNoContext,

NewItem('~T~ile','',0,cmTile,

hcNoContext,

NewItem('~C~ascade','',0,cmCascade,

hcNoContext,

NewItem('~D~ialog', 'F2', kbF2, cmNewDialog, hcNoContext, nil))))))),

nil)))))

end;

procedure TMyApp.NewDialog; var

Bruce: PView; Dialog: PDemoDialog; R: TRect;

C: Word; begin

R.Assign(20, 6, 60, 19);

Dialog := New(PDemoDialog, Init(R, 'Demo Dialog')); with Dialog^ do

begin

R.Assign(3, 3, 18, 6);

Bruce := New(PCheckBoxes, Init(R, NewSItem('~H~varti', NewSItem('~T~ilset', NewSItem('~J~arlsberg',

nil)))

));

Insert(Bruce); R.Assign(2, 2, 10, 3);

Insert(New(PLabel, Init(R, 'Cheeses', Bruce))); R.Assign(22, 3, 34, 6);

Bruce := New(PRadioButtons, Init(R, NewSItem('~S~olid',

318

Лабораторная работа № 27

 

 

NewSItem('~R~unny',

NewSItem('~M~elted',

nil)))

));

Insert(Bruce); R.Assign(21, 2, 33, 3);

Insert(New(PLabel, Init(R, 'Consistency', Bruce))); R.Assign(3, 8, 37, 9);

Bruce := New(PInputLine, Init(R, 34)); Insert(Bruce);

R.Assign(2, 7, 24, 8);

Insert(New(PLabel, Init(R, 'Delivery instructions', Bruce))); R.Assign(15, 10, 25, 12);

Insert(New(PButton, Init(R, '~O~k', cmOK, bfDefault))); R.Assign(28, 10, 38, 12);

Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal))); end;

Dialog^.SetData(DemoDialogData);

C := DeskTop^.ExecView(Dialog);

if C <> cmCancel then Dialog^.GetData(DemoDialogData); Dispose(Dialog, Done);

end;

procedure TMyApp.NewWindow; var

Window: PDemoWindow; R: TRect;

begin Inc(WinCount); R.Assign(0,0,30,7);

R.Move(Random(58),Random(16)); Window:=New(PDemoWindow, Init(R,'Demo Window ', WinCount)); Window^.Options:=Window^.Options+ofTileable; DeskTop^.Insert(Window);

end;

procedure TMyApp.HandleEvent(var Event: TEvent); var R: TRect;

begin TApplication.HandleEvent(Event); if Event.What=evCommand then begin

case Event.Command of cmNewWin: NewWindow;

Диалоговые окна

319

 

 

cmNewDialog: NewDialog; cmTile:

begin DeskTop^.GetExtent(R); DeskTop^.Tile(R);

end;

cmCascade: begin

DeskTop^.GetExtent(R);

DeskTop^.Cascade(R); end

else Exit; end;

ClearEvent(Event);

end;

end; BEGIN

with DemoDialogData do begin

CheckboxData := 1;

RadioButtonData := 2; InputLineData := 'Phone home.';

end;

ReadFile;

MyApp.Init;

MyApp.Run;

MyApp.Done;

DoneFile;

END.

Задание для самостоятельнойработы

1.Используя вышеприведенный текст программы TFirst6, создайте про- грамму, реализующую идею электронной записной книжки. Ваша книжка должна содержать сведения о студентах Вашей группы (фами- лия, имя, отчество, год рождения, год поступления, номер зачетной книжки, домашний адрес, номер телефона, сведения о родителях и т. д.). Предусмотрите возможность просмотра записей и их изменения и дополнения в режиме диалога с пользователем.

320

Приложение

ВСТРОЕННЫЙ АССЕМБЛЕР

Ассемблером называется машинно-зависимый компилятор, преоб-

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

Встроенный ассемблер имеется в версиях 6.0 и 7.0 Турбо Паскаля и представляет собой мощный инструмент, расширяющий возможно- сти ПК.

ОПИСАНИЕ МП 8086/8088

Встроенный ассемблер дает возможность программировать на уровне отдельных машинных инструкций. Это главное отличие

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

Чтобы использовать средства ассемблера, необходимо представ- лять себе детали архитектуры микропроцессоров Intel 80х86. К это- му семейству относятся микропроцессоры:

8086 16-разрядный микропроцессор, используемый в ПК IBM

PC/XT;

8088 аналог 8086, отличается от него только взаимодействи- ем с памятью: 8086 может обмениваться с памятью как байтами, так и 16-разрядными словами, в то время как 8088 только байта- ми;

Встроенный ассемблер

321

 

 

80286 улучшенный вариант 8086, используемый в ПК IBM AT; может работать в двух режимах: в реальном режиме, полностью эмулирующем работу МП 8086, и в защищенном режиме, в котором способен адресовать память до 16 Мбайт (в реальном до 1 Мбайт);

80386 32-разрядный вариант 80286; способен адресовать до 4

Гбайт;

80486 комбинация 80386/80387, т.е. имеет внутреннюю под- систему реализации операций с плавающей точкой;

80586 (Pentium) имеет ряд усовершенствований, обеспечи- вающих ему увеличение производительности в 2...3 раза по сравне- нию с 80486, в том числе возможность обрабатывать 64 – разряд- ные числа.

Микропроцессоры этого семейства наращивают свои возможности в перечисленном порядке, но строго совместимы от младших моде- лей к старшим: все, что может 8086/8088, реализует и Pentium, но не наоборот. Ниже обсуждается архитектура (внутреннее устройство, способы адресации и система команд) МП 8086/8088.

Регистры

В МП 8086/8088 имеется 14 регистров. В функциональном отноше- нии они делятся на группы:

регистры общего назначения (AX, BX, CX, DX); предназначены для хранения операндов и выполнения основных команд; любой из них может использоваться как совокупность двух независя- щих друг от друга 8 – разрядных регистров: старшего байта (АН, ВН, СН, DH) и младшего байта (AL, BL, CL, DL); например, АХ со-

стоит из АН и AL;

сегментные регистры (CS, DS, SS, ES); используются для указа- ния сегмента при адресации памяти;

регистрыуказатели (SP, BP, IP); используются для указания смещения при адресации памяти;

индексные регистры (SI, DI); применяются для индексной адреса- ции;

регистр флагов; используется для хранения признаков состояния процессора.

322

Приложение

 

 

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

Регистр АХ. Является основным сумматором. Используется во всех арифметических операциях (сложить, умножить и т.п.). Только с помощью АХ и его полурегистров AH/AL возможен обмен данными с портами ввода/вывода.

Регистр BX. Используется как сумматор в арифметических операциях, а также как базовый регистр при индексной адресации.

Регистр CX. В основном используется как счетчик при вы- полнении операций повторения и сдвига. Может также участвовать в арифметических операциях.

Регистр DX. Используется как регистр данных в операциях ввода/вывода, а также как сумматор при обработке длинных целых чисел (32-разрядных).

Регистр CS. Содержит номер сегмента памяти (сегмента ко- да), в котором располагается текущая машинная инструкция. Для

получения полного адреса следующей команды его содержимое сдвигается влево на 4 разряда и складывается с регистром- указателем IP. Содержимое CS автоматически изменяется в коман- дах дальнего (межсегментного) перехода и вызова процедур.

Регистр IP. Определяет смещение относительно начала сег- мента кода CS очередной исполняемой машинной инструкции. Со- держимое IP автоматически изменяется в ходе исполнения инст- рукции, обеспечивая правильный порядок выборки команд из па- мяти.

Регистр DS. Содержит номер сегмента памяти (сегмента дан- ных), в котором располагаются данные (константы и переменные). Все глобальные переменные и типизированные константы про- граммы Турбо Паскаля всегда располагаются в единственном сег- менте, адресуемом этим регистром.

Регистр SS. Содержит номер сегмента стека. Стек это уча- сток автоматически адресуемой памяти, предназначенный для вре- менного хранения операндов. С помощью стека Турбо Паскаль ор- ганизует обмен данными между программой и процедурами, кроме того, в нем он размещает все локальные переменные (т.е. перемен-