Основы программирования (947332), страница 49
Текст из файла (страница 49)
Разработать программу, обеспечивающую вывод «бегущей» строки. Направление движения строки по экрану - вверх-вниз.Для создания изображения используем возможности модуля Graph, затем перепишем изображение из видеопамяти в буфер, расположенный в динамической памяти, и перейдя в режим 200*320, организуем циклическийвывод изображения напрямую в видеобуфер.
Стирание старого изображениябудем выполнять чистой кромкой образа (образ «не прозрачный»).Переход в другой, не поддерживаемый Borland Pascal графический режим, будем осуществлять, используя ресурсы модуля Dos, описанные далее.Program ex;Uses Graph, CrU Dos;TypeScreenType=array [0,.199,0..319J of byte; {массив для храненияобраза экрана - формат видеобуфера}ImageType=array[0..999]ofbyte; {развертка изображения}ScrTypePtr=^ScreenType; {указатель на массив образа экрана}ImageTypePtr=^^ImageType; {указатель на развертку изображения}291Часть L Основы алгоритмизации и процедурное программирование{процедура установки режима с номером mode}Procedure SetBIOSMode(mode:byte);Var r:registers;Beginr.AL:=mode;{запись номера режима в регистр AL}кАН:=0;{запись номера функции в регистр АН}intr($10,r);{вызов 0-й функции 10-го прерывания}End;{основная программа}VarDriver, Mode .'Integer;s:string;ij, n, m, l,y, dy: integer;Active_Ptr:ScrTypePtr; {указатель на тип "образ экрана"}Image:ImageTypePtr; {указатель на развертку изображения}Begin{формирование изображения и сохранение его в памяти}Driver: =Detect; InitGraph(Driver,Mode, ");s:='ABCDEF\SetColor(4); SetTextStylefGothicFont, HorizDir, 3);OutTextXY(2,2,s);n:=TextHeight(s)+3;m:^TextWidth(s)+3;GetMem(Image,(n+l)*(m+])); {получение памяти для записиизображения}1:=0;for i:=0 to ndofor J: =0 to mdobeginimage^[l]:=Lo(GetPixel(j,i)); {запись изображения в буфер}1:4+1;end;CloseGraph;{запись изображения «напрямую» в видеобуфер}SetBIOSMode($13); {установка 19-го графического режима}Active_Ptr:=Ptr($AOOO,0); {стандартный адрес видеобуфера}у:-0;dy~l;{покадровый вывод изображения}repeat{побайтная запись изображения в видеобуфер}1:=0;for i:=0 to п do2928.
Управление техническими средствами и взаимодействие с MS DOSforj:=Oto т dobeginActive_Ptr''[y+i+]0j+20J:=image^flJ;1:4+1;end;for i:=J to 1000 do Delay(3000); {задержка}Inc(y,dy); {смещение изображения}if(y>120) or (y<0) then dy:='dy; {организация колебательногодвижения}until KeyPressed;SetBIOSMode(3);{возврат к стандартному текстовому режиму}End.8.8. Взаимодействие с драйвером мышиМышь - манипулятор, движение которого по столу или другой поверхности преобразуется в перемещение специального курсора мыши на экране.С ее помощью мы можем «указать» на какую-либо область экрана и, нажимая клавиши мыши, заказать некоторую обработку.Для управления мышью программы, написанные на Borland Pascal, используют драйвер мыши, предоставляемый BIOS. Вызов этого драйвера осуществляется через инициацию прерывания с номером ЗЗ15 = 51 ю (int 33h ~на ассемблере).Драйвер мыши реализует выполнение основных операций с мышью:• инициализирует мышь (с проверкой наличия);• устанавливает курсор мыши в заданное место экрана;• определяет местоположение курсора мыши и состояния ее клавиш(нажаты или нет);• управляет видимостью курсора мыши.К сожалению, библиотеки Borland Pascal не включают функций обращения к драйверу мыши, и его вызов приходится осуществлять через процедуру активизации обработчиков прерываний, определенную в модуле Dos.Процедура Intr(numlnt:byte; Var Regs:Register) - активизирует обработчик прерывания с номером numlnt.
Через параметр Regs типа Registers организуется доступ к содержимому регистров (внутренней памяти) процессора:Туре Registers = record case Integer of0: (AX,BXCXDXBP^DI,DS,ES,Flags: word);J: (AL,AH,BL,BH,CL,CH,DL,DH:byte);end;...Обмен данными между программой и драйвером мыши выполняется через регистры, указанные в описании драйвера. Так, номер вызываемой функ293Часть I. Основы алгоритмизации и процедурное программированиеции помещается в регистр АХ, а для передачи или получения дополнительной информации используются регистры СХ, DX.Ниже приводится текст модуля, содержащего ресурсы, которые обеспечивают доступ к драйверу мыши.Unit Mouse;InterfaceUses Dos;Function ResetMouse:Boolean; {проверить наличие}Procedure ShowMouseCursor; {показать курсор мыши}Procedure HideMouseCursor; {спрятать курсор мыши}{прочитать состояние мыши}Procedure ReadMouseStatefVar х, у:integer;{координаты мыши}Var LeftButton,{нажата левая клавиша}MiddleButton,{нажата средняя клавиша}RightButton:boolean); {нажата правая клавиша}Procedure MoveMouseCursor(x,y:integer); {установить курсор мышив точку с заданными координатами}Implementation{проверить наличие}Function ReSetMouse.Boolean;Var г:Registers;Beginr.AX:^0;intr($33,r);ReSetMouse: =r.AX=$FFFF;End;{показать курсор мыши}Procedure ShowMouseCursor;Var r: Registers;BeginKAX:=I;intr($33,r);End;{спрятать курсор мыши}Procedure HideMouseCursor;Var r: Registers;BeginKAX:^2;intr($33,r);End;2948.
Управление техническими средствами и взаимодействие с MS DOS{прочитать состояние мыши}Procedure ReadMouseStatefVar х,у:integer;{координаты мыши}Var LeftButton,{нажата левая клавиша}MiddleButton,{нажата средняя клавиша}RightButton:boolean); {нажата правая клавиша}Var г:Registers;Beginr.AX:=3;intr($33,r);х:=кСХ;y:==r.DX;LeftButton-fr.BXAND 1)<>0;RightButton:=(r.BXAND 2)<>0;MiddleButton:^(KBXAND 4)<>0;End;{установить курсор мыши}Procedure MoveMouseCursor(x,y: integer);Var r: Registers;BeginKAX:=4;r.CX:=x;KDX:=y;intr($33,r);End;EndРазработка программ, использующих мышь, имеет свои особенности.
Вотличие от клавиатуры, ввод информации с которой осуществляется пользователем по запросу программы, состояние мыши (перемещение и положениеклавиш) может изменяться пользователем в любой момент времени, независимо от программы. Следовательно, программы, работающие с мышью,должны циклически опрашивать состояние мыши и при его измененииосуществлять требуемые операции.На рис.
8.12 показано, как программа определяет моменты нажатия и отпускания клавиш (при выполнении опроса, если клавиша нажата, переменной Left присваивается значение true, а если - не нажата, то false).Учитывать приходится также режим экрана, который использует программа, так как координаты курсора мыши на экране и в текстовом и в графическом режимах определяются в пикселях.Взаимодействие с мышью в текстовом режиме. Координаты мышипри работе с ней в текстовом режиме необходимо пересчитывать, причем независимо от реального размера знакоместа считается, что оно имеет размер8x8 пикселей.295Часть L Основы алгоритмизации и процедурное программированиеКлавишане нажата ГСостояниеклавишиКлавиша нажата1Клавишане нажатаОпросыДействияпрограммы [^СостояниепеременнойLeft = tmeLeft = falseILeft = falseРис.
8.12. Циклический опрос состояния мыши для фиксащ{имоментов нажатия и отпускания клавиши мышиПример 8.9. Разработать программу, демонстрирующую особенностииспользования мыши в текстовом режиме. При нажатии левой клавиши мыши программа должна высвечивать координаты точки. Выход осуществитьпри нажатии левой клавиши мыши, когда ее курсор находится в окне «Конец» (рис. 8.13).Управление разрабатываемой программой будет реализовано только посредством мыши. Вначале проверим наличие мыши, нарисуем окно Конец(«кнопка»), установим i^pcop в левый верхний угол экрана. Затем будем отслеживать перемещение курсора, мыши и нажатие ее левой клавиши. Есликлавиша нажата, то определяем местоположение курсора, проверяем, не находится ли он над окном Конец, и если нет, то выводим его координаты. После этого ожидаем отпускания клавиши, чтобы повторно не выводить координаты курсора.::||Щ||?|^||iiiii^iiasSsКонец|||||||||Щ,-?ciif:f|§iiРис.
8.13. Вид экрана в процессе работы программы2968. Управление техническими средствами и взаимодействие с MS DOSProgram ex;Uses CrtMouse;Var x,y,xt,yt: integer;l,m,r:boolean;exit_m: boolean;Begin Clrscr;if not ReSetMouse then {проверка наличия мыши}beginWriteLn('Mbitub не загруэюена');Halt(l);endelse WriteLn('Mbiiub подключена, *);ShowMouseCursor; {покажем курсор: курсор устанавливаетсяв центр экрана}MoveMouseCursor(0,0); {поместим курсор в левыйверхний угол экрана}Window(70,1,80,3); {нарисуем окно-кнопку «Конец»}Textattr:=^]6*J+14;Clrscr;Gotoxy(2,2);WriteCKoнeц');Windowd 1M25);Gotoxy(],3);Textattr:=5*]6-^9;repeat{цикл обработки нажатий клавиши}ReadMouseState(x,y, /, т, г);if I then {если нажата левая кнопка }begin{пересчет координат курсора для текстового режима}xt:=x div 8+1;yt:=y div 8+1;exitjn:=(xt>=70) and (xt< =80) and (yt> =1) and (yt< =3);if not exitjn thenbeginGotoxy(xt,yt);HideMouseCursor; {если не убирать курсор,то курсор мыши будет затерт строкой}Write('x= \ xt:4, ' у= \ yt:4);ShowMouseCursor; {теперь символ под курсором«просвечивает» другим цветом}end;repeat ReadMouseState(x,y,l,m,r) until not I; {ждемотпускания левой кнопки}end;until exitjn; {до «нажатия кнопки» Конец}Textattr:=7;Clrscr;End297Часть 1.
Основы алгоритмизации и процедурноепрограммированиеDrawing with mouse:?MJ.Курсор мышиРис. 8.14. Вид экрана при выполнении программыВзаимодействие с мышью в графическом режиме* При использовании мыши в графическом режиме также приходится выполнять циклическийопрос состояния мыши для определения момента нажатия клавиши.Пример 8.10. Разработать программу рисования мышью при нажатойлевой клавише: точка рисуется при каждом опросе состояния мыши, есликлавиша остается нажатой. Реализовать двойное управление (с клавиатуры имышью): выход ~ при нажатии мышью кнопки Exit на экране или клавишиEsc на клавиатуре (рис. 8.14).Program ex;Uses Mouse,Crt,Graph;Varx,y:mteger;l,m,r: boolean;exitjn: boolean;driver,mode: integer;ch:char;{процедура рисования кнопки}Procedure Button(xI,yI,x2,y2:integer;s:string);BeginSetColor(O);SetFillStyle(l8);Bar(xl,yl,x2,y2);{рисуем контур кнопки}SetFillStyleOJ);Ваг(х1-^2,у1+2,х2'3,у2гЗ); {рисуем тени кнопки}SetFillStyle(ll5);Bar(x],ylxl+ly2);2988.
Управление техническими средствами и взаимодействие с MS DOSBar(xl+2,у]+Ixl+2,y2-J);Bar(x],yJ,x2,yI+J);Bar(xl+lyl+1x2'lyl+2);SetColor(4);SetTextStyle(lA3);OutTextXY(xl^20,yl+3,s);End;{основная программа}BeginClrscr;if not ReSetMouse then {проверим наличие мыши}beginWriteLnCMouse not found, *);halt(l);end;driver: ^'detect;InitGraph(driver,mode,' ');SetColor(4);OuttextXY(10,]0, 'Drawing with mouse:');ShowMouseCursor;{покажем курсор мыши}SetBkColor(3);Button (500J0,600,50, 'Exit');repeat {цикл опроса состояния клавиатуры и мыши}if keypressed then ch:-readkey {если нажата клавиша наклавиатуре, то введем код}else {если клавиша не нажата, то}beginReadMouseState(x,y,l,m,r); {опросим состояние мыши}Exitjn: ==(х> =500)and(x< =600)and(y>=10)and(y< =50);if not Exitjn and I then {если не «нажата» кнопка «Exit»на экране}begin {изобразим точку на экране}HideMouseCursor;PutPixel(x,y4);ShowMouseCursor;end;enduntil (exitjn and I) or (ch=#27);repeat ReadMouseState(x,y,l,m,r) until not I; {ожидаем отпусканияклавиши}CloseGraph;End299Часть I.