Rapid-Q Documentation by William Yu (c)1999-2000 Глава 5



5. Введение в формы. (Introduction to forms)

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

5.1  Что такое форма? (What's in a form? )
Форма (окно) это основной контейнер который отображается на экране и в котором могут размещаться другие компоненты.
Формы могут быть нескольких видов. Ниже показаны те, которые можно использовать в Rapid-Q. (Вы также можете определять собственные очертания форм, используя метод SHAPEFORM
 

По умолчанию форма имеет стиль bsSizeable. Для чего может понадобится стиль bsNone?. Для создания игр ;-). В самом деле, если форма максимизирована (maximized, растянута на весь экран), то вы можете использовать весь экран для вашей игры. Это может пригодиться и для других целей. MSIE использует такую формы для полноэкранного веб-броузера. Значения переменных  bsNone = 0, bsSingle = 1 и т.п можно найти в файле RAPIDQ.INC, где содержатся значения параметров для компонентов Rapid-Q. Эти мнемонические имена более легки для запоминания чем просто цифры.

          $INCLUDE "RAPIDQ.INC"

          DIM Form AS QFORM
          Form.BorderStyle = bsDialog
          Form.ShowModal

Для bsSingle форма выглядит также, как и для bsSizeable, за исключением того, что  нельзя изменять ее размер. Во многих случаях используются только два вида форм - bsSizeable и  bsDialog.

5.2  Добавление компонентов на форму (Adding components to a form )


Из примера в предыдущей главе, вы могли видеть, что чтобы добавить компонент на форму необходимо задать свойство компонента Parent.

        DIM Form AS QForm
        DIM Button AS QButton

        Button.Parent = Form       '' Add button to form

Представьте программу с несколькими формами. Все видимые компоненты должны иметь свойство Parent (родитель). Такие компоненты, как QMENUITEM, и  QTIMER не имеют свойства Parent. Хотя QMENUITEM является видимым (visible) компонентом, его родителем могут быть только компоненты  QMAINMENU или QPOPUPMENU. В данном случае, вместо ипользования свойства Parent , для добавления пункта меню необходимо использовать метод  Add (добавить) или  Insert (вставить).
Если не задать свойство Parent , то компонент остается невидимым. В случае QCANVAS или QIMAGE вы получите сообщение об ошибке если попытаетесь рисовать на таком компоненте. Вы не можете рисовать на невидимом компоненте. В большинстве случаев свойство Parent необходимо задавать первым, прежде чем производить какие-то действия с этим компонентом. Для того, чтобы скрыть компонент, вы можете использовать свойство Visible (видимость).  Visible=0 - скрыть компонент,  Visible=1 - показать компонент.

5.3  Отслеживание позиции мыши на форме (Tracking the mouse position on a form)

Можно использовать MouseX и MouseY для отслеживания позиции мыши на форме, но это устаревшие методы. Лучше обрабатывать
событие OnMouseMove , через которое передаются координаты X и Y положения курсора мыши относительно компонента.
 
5.4  Особые события для формы ( Special events for forms )
 
Существует несколько специальных событий которые обрабатываются только в форме.  Наиболее важное из них это событие OnResize.
Оно происходит когда пользователь нажимает кнопку максимизировать окно или  изменяет размер (ресайзит - resize ) окна.
Ваша программа может перехватывать это событие и соответственно изменять размеры контролов. Если вы не хотите менять размеры формы, используйте другой BorderStyle стиль окна, как было указано выше.
Другое специальное событие - это нажатие клавиши. Я предлагаю использовать OnKeyDown вместо OnKeyPress.
Разница состоит в том, что OnKeyDown  может обрабатывать нажатие специальных клавиш, и определять состояния клавиш Shift, Alt  и Ctrl.  Если вашему приложению не требуется обрабатывать нажатие расширенных клавиш, то можно использовать OnKeyPress .
Обработка событий клавиатуры может требоваться для многих приложений, таких как клавиатурные тренажеры, игры, и т.п.
Может смущать тот факт, что OnKeyDown и OnKeyPress возвращают дополнительные параметры. Обработку дополнительных параметров мы рассмотрим позже.

       SUB AddButtonClick
        '' Do stuff
      END SUB

      AddButton.OnClick = AddButtonClick

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

      SUB KeyPressed(Key AS WORD)
        '' Do stuff
        PRINT Key
      END SUB

      Form.OnKeyPress = KeyPressed

Нажатая клавиша возвращает значение в переменной Key. Вы можете назвать эту переменную как угодно, но ваша SUB должна иметь этот параметр. Rapid-Q допускает использование большее число параметров в этой SUB, но как минимум один параметр должен быть.
Для OnKeyDown должны быть переданы два параметра.

      SUB KeyDown(Key AS WORD, Shift AS INTEGER)
        '' Do stuff
        PRINT Key;" ";Shift
      END SUB

      Form.OnKeyDown = KeyDown

Существует три состояния Shift - ShiftDown, AltDown, и  CtrlDown. Будьте осторожны с состоянием ShiftDown . В отличие от OnKeyPress которое обрабатывает все состояния ShiftDown, OnKeyDown  не делает этого. Это означает, что если вы нажимаете SHIFT+i  вы изменяете  регистр  (UCASE$(Key)).  Обработка расширенной клавиатуры значительно отличается от обработки в Qbasic. Например в Qbasic нажатие на клавиши -стрелки обработать несложно

    DO
      A$=INKEY$
      IF A$=CHR$(0)+"H" THEN PRINT "Up arrow key pressed"
    LOOP

При использовании OnKeyDown возвращается код виртуальной клавиши, который не является двухбайтным, как в QBasic. Стрелка вверх имеет код 38, влево - 37, вправо - 39 и вниз - 40.

5.5   Диалоговые окна ( Dialog Boxes )

Специальным типом формы является простое диалоговое окно (dialog box). Диалоговое окно это стандартный интерфейс, расширяющий возможности вашей основной формы. Обычно вам не нужно создавать  диалоговое окно как ваша основную форму. например, пусть главное окно содержит три кнопки выбора.


Для каждого выбора (за исключением может быть пункта 3), вы должны создать диалоговое окно для обработки ввода информации от пользователя. Когда пользователь нажимает на первую клавишу, диалоговое окно может иметь следующий вид.
 


Эти красивые кнопки являются кнопками особого вида (custom buttons). Описание видов кнопок находится в файле  RAPIDQ.INC  

     OKButton1.Kind = bkOK
     CancelButton1.Kind = bkCancel

Отлично, но как узнать какую кнопку нажал пользователь  -  OK или CANCEL?  Существует два способа для этого, оба используют свойство ModalResult.
Запомните, как вы вызывали диалоговое окно.

   IF Dialog1.ShowModal = mrOK THEN
      '' User pressed OK
   ELSE
      '' User cancelled
   END IF

ModalResult  это свойство как QButtons, так и QForms. Когда вы делаете

     OKButton1.Kind = bkOK

вы автоматически выполняете

     OKButton1.ModalResult = mrOK

Это означает, что когда вы нажимаете кнопку ОК, ModalResult возвращает mrOK. Этот результат автоматически закрывает вашу форму Dialog1.
Другой менее элегантный способ заключается в простом присваивании  ModalResult вашей форме. Например :

      SUB ButtonClick
          Dialog1.ModalResult = mrOK
      END SUB

      OKButton1.ModalResult = mrNone   '' No result
      OKButton1.OnClick = ButtonClick

По этому сценарию нажатие кнопки будет передавать управление процедуре ButtonClick,  где устанавливается свойство ModalResult, что приводит к тому же результату как и в предыдущем примере.

5.6  Использование метода CREATE   (Using the CREATE Method )

В большинстве случаев использование CREATE  предпочтительнее DIM, потому что исходный текст получается более кратким и наглядным.  
        DIM MainForm AS QForm
            MainForm.Left = 100
            MainForm.Top = 50
            MainForm.Height = 300
            MainForm.Width = 400
            MainForm.Caption = "Hello world!"

используя CREATE:

        CREATE MainForm AS QForm
           Left = 100
           Top = 50
           Height = 300
           Width = 400
           Caption = "Hello world!"
        END CREATE

5.7  Вложенные CREATE ( Embedding CREATEs )
Также при использовании метода CREATE можно использовать "вложение" компонентов
        CREATE MainForm AS QForm
           Center

           CREATE Button1 AS QButton
              Left = 10: Top = 10: Height = 20: Width = 20
           END CREATE

           CREATE Button2 AS QButton
              Left = 40: Top = 10: Height = 20: Width = 20
           END CREATE

           ShowModal
        END CREATE
Отметим, что при этом не требуется использовать свойство Parent , т.к. компилятор понимает, что "вложенный" компонент Button1 имеет родителем форму MainForm и автоматически устанавливает свойство Button1.Parent = MainForm . Rapid-Q допускает 25 уровней вложения. Я не думаю что реально может использоваться больше 4-5 уровней. Компоненты, не имеющие свойства Parent (невидимые компоненты) не могут "вкладываться".


5.8 Создание меню (Создание Menus )
Создание меню с использованием метода Create происходит аналогично
        CREATE MainForm AS QForm  '  0 уровень
           Center

           CREATE MainMenu AS QMainMenu  '  1 уровень

              CREATE FileMenu AS QMenuItem '  2 уровень

                Caption = "&File"

                CREATE OpenItem AS QMenuItem '  3 уровень
                  Caption = "&Open"
                END CREATE
                CREATE SaveItem AS QMenuItem
                  Caption = "&Save"
                END CREATE             '  3 уровень (конец)


              END CREATE '  2 уровень (конец)

           END CREATE '  1 уровень (конец)

           ShowModal
        END CREATE '  0 уровень (конец)
Вместо использования свойства Parent для меню применяется метод AddItems.  Использование Create проще для понимания.

Prev Глава Up Содержание Next Глава
ODY>