Графические интерфейсы и средства их разработки. Класс XmGadget содержит подклассы

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

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

¦ Следует избегать сложных структур (типа дерева) для связи различных меню. В одну линейку меню лучше всего включать не более шести меню, каждое из которых будет содержать не более шести опций.

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

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

¦ При активизации всех пиктограмм, как отмечалось выше, следует использовать двойной щелчок мышью. А для получения аналогичного результата для пиктограмм объектов, которые активизируются одинарным щелчком мышью, рекомендуется также запрограммировать двойной щелчок. Многие опции, например из меню Control Panel, выглядят как пиктограммы, но являются объектами, которые активизируются одинарным щелчком мышью. Следует предусмотреть возможное поведение пользователей при работе с такими объектами (т.е. допустить, что они будут дважды щелкать по ним мышью) и помочь им достигнуть желаемого результата.

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

¦ Элементы, общие для различных меню, следует размещать в одном месте. Нопример, кнопки ОК и Cancel должны всегда располагаться одиноково относительно друг друга и занимать одно и то же место в различных диалоговых окнах.

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

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

Эргономических требований к графическим интерфейсам пользователя оказалось явно недостаточно с развитием «мультимедиа» (multimedia) - интерактивных систем, обеспечивающих работы с неподвижными изображениями и движущимся видео, анимированной компьютерной графикой и текстом, речью и высококачественным звуком. Эргономические исследования и разработки этих систем представляют сложную и в профессиональном отношении увлекательную задачу.

Большинство руководителей проектов по разработке приложений, отмечает Б.Тогназзини, ждут завершения проекта, чтобы приступить к интерфейсу. Это напоминает постройку дома, когда архитектора приглашают после возведения каркаса здания. Все разработчики по-разному подходят к организации процесса создания интерфейса. Однако существуют общие моменты, которых следует придерживаться всем разработчикам:

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

2) создание интерфейса - это работо не одиночки, а представителей трех областей: специалиста, который выясняет мнение пользователей об основных элементах интерфейса и описывает их; разработчика интерфейса и создателя графики;

3) один опытный сотрудник должен быть нозначен экспертом по интерфейсу и посредником между рабочей группой и пользователями;

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

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

Предоставлено Салимом Гулом (Saleem Gul) и Томасом Павеком (Tomas Pavek)

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

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

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

Предполагаемая продолжительность: 20 минут

Упражнение 1: Создание проекта

Первым действием является создание проекта среды IDE для разрабатываемого приложения. Дадим проекту имя NumberAddition .

  1. Выберите "Файл" > "Создать проект" . Также можно щелкнуть значок "New Project" на панели инструментов среды IDE.
  2. В области "Categories" выберите узел "Java". В области "Projects" выберите "Java Application". Нажмите кнопку "Далее".
  3. Введите NumberAddition в поле Project Name ("Имя проекта") и укажите путь, например, в вашем основном каталоге, как местоположение проекта.
  4. Установите флажок "Использовать отдельную папку для хранения библиотек" и укажите местоположение папки библиотек (необязательно). Дополнительная информация приведена в статье Предоставление доступа к библиотеке другим пользователям в документе Разработка приложений с помощью NetBeans IDE .
  5. Удалите флажок "Create Main Class", если он установлен.
  6. Нажмите кнопку "Готово".

Упражнение 2: Создание внешнего интерфейса

Для продолжения процесса создания интерфейса необходимо создать контейнер Java, в который будут помещены другие требуемые элементы графического интерфейса. В этом действии контейнер будет создан с помощью элемента JFrame . Контейнер будет помещен в новый пакет, который будет отображаться в узле "Source Packages".

Создание контейнера JFrame

  1. В окне "Проекты" щелкните правой кнопкой мыши узел NumberAddition и выберите Создать > Другие.
  2. В диалоговом окне создания файла выберите категорию Swing GUI Forms и тип файла JFrame Form . Нажмите кнопку "Далее".
  3. Введите NumberAdditionUI в качестве имени класса.
  4. Выберите пакет my.numberaddition .
  5. Нажмите кнопку "Готово".

Среда IDE создает форму NumberAdditionUI и класс NumberAdditionUI в приложении NumberAddition и открывает форму NumberAdditionUI в GUI Builder. Пакет my.NumberAddition заменяет собой пакет по умолчанию.

Добавление элементов: создание внешнего интерфейса

Далее с помощью окна "Palette" внешний интерфейс приложения заполняется панелью JPanel. После этого добавляются три элемента JLabel (текстовые подписи), три элемента JTextField (текстовые поля) и три элемента JButton (кнопки). Если до этого работа с конструктором графического интерфейса пользователя не выполнялась сведения о размещения компонентов см. в разделе Разработка графического пользовательского интерфейса Swing в IDE NetBeans .

После перетаскивания и размещения указанных выше элементов элемент JFrame должен выглядеть так, как показано на рисунке ниже.

Если в правом верхнем углу среды IDE отсутствует окно Palette ("Палитра"), выберите Window ("Окно") > Palette ("Палитра").

  1. Для начала выберите панель из категории Swing Containers ("Контейнеры Swing") в палитре и перетащите ее на JFrame.
  2. Панель JPanel будет выделена. Перейдите к окну "Properties" и нажмите кнопку с многоточием (...) рядом с полем "Border" для выбора стиля границы.
  3. В диалоговом окне "Border" выберите "TitledBorder" из списка и введите Number Addition в поле "Title". Для сохранения изменений и закрытия диалогового окна нажмите кнопку "OK".
  4. Теперь на экране должен отображаться пустой элемент "JFrame" с заголовком "Number Addition", как показано на рисунке. Согласно рисунку добавьте к нему три метки JLabel, три текстовых поля JTextField и три кнопки JButton.

Переименование элементов

На этом этапе будет выполнено переименование элементов, которые были добавлены к элементу JFrame.

  1. Дважды щелкните jLabel1 и измените ntrcn (свойство "text") на First Number .
  2. Дважды щелкните jLabel2 и измените текст на Second Number .
  3. Дважды щелкните jLabel3 и измените текст на Result .
  4. Удалите стандартный текст из jTextField1 . Отображаемый текст можно преобразовать в редактируемый. Для этого щелкните правой кнопкой мыши текстовое поле и выберите "Редактировать текст" во всплывающем меню. При этом может потребоваться восстановить первоначальный размер поля jTextField1 . Повторите это действие для полей jTextField2 и jTextField3 .
  5. Измените отображаемый текст jButton1 на Clear . (Для изменения текста кнопки щелкните кнопку правой кнопкой мыши и выберите "Edit Text". В качестве альтернативы можно щелкнуть кнопку, выдержать паузу и щелкнуть еще раз.)
  6. Измените отображаемый текст jButton2 на Add .
  7. Измените отображаемый текст jButton3 на Exit .

Теперь готовый графический интерфейс должен выглядеть так, как показано на рисунке ниже:

Упражнение 3: Добавление функциональности

В этом упражнении будет добавлена необходимая функциональность к кнопкам "Add", "Clear" и "Exit". Поля jTextField1 и jTextField2 будут использоваться для ввода значений пользователем, а jTextField3 - для вывода результата работы программы. Создаваемая программа представляет собой простейший калькулятор. Итак, приступим!

Добавление функциональности к кнопке "Exit"

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

  1. Щелкните правой кнопкой мыши кнопку "Exit". Во всплывающем меню выберите Events ("События") > Action ("Действие") > actionPerformed. Учтите, что меню содержит множество других событий, на которые может реагировать программа! При выборе события actionPerformed среда IDE автоматически добавит прослушиватель ActionListener к кнопке Exit ("Выход") и создаст метод обработчика для обработки метода прослушивателя actionPerformed.
  2. В среде IDE автоматически открывается окно "Source Code", где отображается место вставки действия, которое должно выполняться кнопкой при ее нажатии (с помощью мыши или клавиатуры). Окно "Source Code" должно содержать следующие строки: private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) { //TODO add your handling code here: }
  3. Теперь добавим код действия, которое должна выполнять кнопка "Exit". Замените строку TODO на System.exit(0); . Готовый код кнопки "Exit" должен выглядеть следующим образом: private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) { System.exit(0); }

Добавление функциональности к кнопке "Clear"

  1. Щелкните правой кнопкой мыши кнопку "Clear" (jButton1). В появившемся меню выберите "Events > Action > actionPerformed".
  2. Нажатие кнопки "Clear" должно приводить к удалению всего текста из всех текстовых полей "jTextField". Для этого следует добавить код, аналогичный приведенному выше. Готовый исходный код должен выглядеть следующим образом: private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){ jTextField1.setText(""); jTextField2.setText(""); jTextField3.setText(""); }

Этот код удаляет текст из всех трех полей JTextField, оставляя их пустыми.

Добавление функциональности к кнопке "Add"

Кнопка "Add" должна выполнять три действия.

  1. Сначала она принимает данные, введенные пользователем в полях jTextField1 и jTextField2 , и преобразовывает их из типа "String" в тип "Float".
  2. Затем она выполнит сложение двух чисел.
  3. И, наконец, она преобразует сумму в тип String и поместит ее в jTextField3 .
Начнем!
  1. Щелкните вкладку "Design" в верхней части рабочей области для возврата к экрану "Form Design".
  2. Щелкните правой кнопкой мыши кнопку "Add" (jButton2). Во всплывающем меню выберите Events ("События") > Action ("Действие") > actionPerformed.
  3. Добавьте код действий, которые должна выполнять кнопка "Add". Готовый исходный код должен выглядеть следующим образом: private void jButton2ActionPerformed(java.awt.event.ActionEvent evt){ // First we define float variables. float num1, num2, result; // We have to parse the text to a type float. num1 = Float.parseFloat(jTextField1.getText()); num2 = Float.parseFloat(jTextField2.getText()); // Now we can perform the addition. result = num1+num2; // We will now pass the value of result to jTextField3. // At the same time, we are going to // change the value of result from a float to a string. jTextField3.setText(String.valueOf(result)); }

Теперь программа полностью готова, и можно приступить к ее сборке и выполнению.

Упражнение 4: Выполнение программы

Для выполнения программы в среде IDE выполните следующие действия:

  1. Выберите Run ("Запуск") > Run Main Project ("Запуск главного проекта") (как вариант, нажмите F6).

    Примечание. При открытии окна с указанием того, что для Project NumberAddition не задан основной класс, следует выбрать my.NumberAddition.NumberAdditionUI в качестве основного класса в том же окне и нажать кнопку ОК.

Для запуска программы вне среды IDE выполните следующие действия:

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

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

Можно также запустить приложение из командной строки.

Для запуска приложения из командной строки выполните следующие действия:

  1. Вызовите командную строку или окно терминала.
  2. В командной строке измените текущий каталог на каталог NumberAddition/dist .
  3. В командной строке введите следующий оператор: java -jar NumberAddition.jar

    Примечание. Убедитесь, что my.NumberAddition.NumberAdditionUI задан как основной класс до запуска приложения. Для провери этого, щелкните правой кнопкой узел мыши узел проекта NumberAddition на панели "Проекты", выберите "Свойства" во всплывающем меню и выберите категорию "Выполнить" в диалоговом окне "Свойства проекта". В поле "Основной класс" должно отображаться my.numberaddition.NumberAdditionUI .

Механизм обработки событий

В этом руководстве было рассмотрено реагирование на простое событие нажатия кнопки. Существует множество событий, на которые может реагировать приложение. Просмотреть в среде IDE список доступных событий, которые могут обрабатываться элементами графического интерфейса, можно следующим образом:

  1. Вернитесь к файлу NumberAdditionUI.java в редакторе. Щелкните вкладку "Design" для просмотра структуры графического интерфейса в GUI Builder.
  2. Щелкните правой кнопкой мыши любой элемент графического интерфейса и выберите "Events" в появившемся меню. Теперь можно просто изучить содержимое меню, не выбирая каких-либо пунктов.
  3. В качестве альтернативы можно выбрать "Properties" в меню "Window". В окне "Properties" щелкните вкладку "Events". Вкладка "Events" позволяет просмотреть и изменить обработчики событий, связанные с текущим активным элементом графического интерфейса.
  4. Приложение также может реагировать на нажатие клавиш, одинарный, двойной или тройной щелчок мышью, перемещение указателя мыши, изменение размера окна и перемещение фокуса ввода. Меню "Events" позволяет автоматически создать обработчики событий для всех этих событий. Наиболее распространенным из них является событие "Action". (Для получения дополнительных сведений см. практические рекомендации по обработке событий в руководстве Sun Java Events Tutorial .)

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

  1. Вернитесь к файлу NumberAdditionUI.java в редакторе. Щелкните вкладку "Source" для просмотра исходного кода графического интерфейса.
  2. Выполните прокрутку вниз и просмотрите реализованные методы jButton1ActionPerformed() , jButton2ActionPerformed() и jButton3ActionPerformed() . Эти методы называются обработчиками событий.
  3. Теперь перейдите к методу initComponents() . Если этот метод отсутствует, найдите строку Generated Code и щелкните знак + рядом с этой строкой для отображения скрытого метода initComponents() .
  4. Обратите внимание на синий блок, окружающий метод initComponents() . Этот код был автоматически создан средой IDE и не может быть изменен пользователем.
  5. Теперь посмотрите на сам метод initComponents() . Помимо прочего, он содержит код, инициализирующий элементы графического интерфейса и помещающий их в форму. Этот код создается и обновляется автоматически при размещении и изменении элементов в режиме проектирования.
  6. В методе initComponents() найдите следующий фрагмент: jButton3.setText("Exit"); jButton3.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton3ActionPerformed(evt); } });

    В этом месте к элементу графического интерфейса, в данном случае к jButton3 , добавляется объект прослушивания событий "ActionListener". Интерфейс "ActionListener" имеет метод "actionPerformed" объекта "ActionEvent", который реализуется путем простого вызова обработчика событий jButton3ActionPerformed . Теперь эта кнопка реагирует на события действий. Каждый раз при нажатии кнопки создается событие "ActionEvent", которое передается в метод "actionPerformed" интерфейса прослушивания событий, исполняющий код, предусмотренный разработчиком для этого события в обработчике событий.

  7. Учебная карта по приложениям с графическим интерфейсом Java

09 июля 2003г.

С появлением разнообразных визуальных средств разработки приложений, написание графических интерфейсов программ превратилось в подобие детской игры. Ткнул мышкой - появилась формочка, второй раз ткнул - кнопочка нарисовалась. Как мне кажется, многие сейчас не помышляют об ином способе программирования в графической среде. Безусловно, против прогресса не попрешь, при написании больших проектов все эти удобства очень даже кстати. Но разговор не об этом. Иногда дело доходит до абсурда, примитивное приложение пишется с использованием MFC, VCL etc. Такие программы жрут память, как термиты и занимают, своим жирным телом, лишнее дисковое пространство. Как правило, MFC/VCL аналоги "весят" в десять - двадцать раз больше, чем программы написанные на чистом API. А Visual Basic (да простит меня бог за это словосочетание) с его msvbvmXX.dll? Да и системных ресурсов расходуется значительно больше (в несколько раз). Бедные пользователи, отказывая себе в пиве, копят ассигнации на покупку нового железа. Разве не жалко - бедненьких? Не только же программерам пиво пить? Есть еще один положительный момент в API кодинге, программист становится ближе к операционной системе. Соответственно - лучше ее понимает и контролирует. Да и просто - это очень увлекательное занятие. Повторюсь, все вышесказанное относится именно к маленьким, простеньким программкам, в больших проектах все обстоит совершенно иначе.

Надеюсь, убедил. Поехали.

Мы рассмотрим создание простенького оконного интерфейса с минимальной функциональностью. Это будет простое окошко с двумя полями ввода и двумя кнопочками. При нажатии на кнопку "Copy", текст из первого поля ввода будет скопирован во второе. При нажатии на кнопку "Close", программа завершит свою работу. В дальнейшем оно может послужить шаблоном для написания других, более сложных, приложений. Будем общаться на языке C/C++, хотя и Delphi не обидим. Общий принцип один и тот же, различается только синтаксис. Чтобы работать с системными сообщениями и API-функциями, необходимо к своему проекту подключить заголовочные файлы; в C/C++ это windows.h, в Delphi это модули windows и messages.

Любая программа в ОС Windows состоит из трех основных частей: главной функции, цикла обработки сообщений и оконной функции, которая обрабатывает все сообщения, посылаемые окну.

Наша программа начинает выполняться с функции WinMain(). Это и есть главная функция. Функция WinMain() выполняет, обычно, следующие задачи:

  • Определяет класс окна. Не путать с классом ООП.
  • Регистрирует данный класс в системе.
  • Создает главное окно приложения и другие элементы управления.
  • Отображает окно на экране.
  • Запускает цикл обработки сообщений.
  • Объявляется она вот каким образом: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) Разберемся с параметрами:
    • hInstance - дескриптор текущего экземпляра приложения.
    • hPrevInstance - дескриптор предыдущего экземпляра приложения, если оно запущено.
    • lpCmdLine - указатель на строку, содержащую параметры передаваемые программе при запуске.
    • nCmdShow - константа определяющая способ отображения окна. (Смотри константы SW_).

В Delphi мы не увидим такой картины, в этой среде разработки главная функция скрывается от программиста компилятором. Хотя, несомненно, она присутствует в конечном коде. Для регистрации класса окна, необходимо заполнить поля структуры типа WNDCLASS (в Delphi TWNDCLASS). У нас, для этого, объявлена переменная wcl. wcl.hInstance = hInstance; Дескриптор текущего экземпляра приложения, переменная hInstance инициализируется функцией WinMain(). В Delphi инициализируется неявным образом. wcl.lpszClassName = szWinName; Имя класса. Строковую переменную szWinName мы создали и инициализировали предварительно. wcl.lpfnWndProc = WindowFunc; Указатель на оконную функцию. wcl.style = 0; Константа, задающая стиль окна. Для этого используется флаги CS_, я просто обнулил. Можно задавать комбинацию флагов с помощью битовой операции "или". wcl.hIcon = LoadIcon(NULL, IDI_ASTERISK); Дескриптор иконки приложения, возвращаемый функцией LoadIcon(). Я загрузил стандартную иконку. Смотри константы IDI_. wcl.hCursor = LoadCursor(NULL,IDC_ARROW); Дескриптор курсора приложения, возвращаемый функцией LoadCursor(). Я загрузил стандартную стрелочку. Смотри константы IDC_. wcl.lpszMenuName = NULL; Указатель на строку, задающую имя ресурса меню для данного оконного класса. Нет меню, нет и указателя. wcl.cbClsExtra = 0; Зарезервированное поле. Обнуляем. wcl.cbWndExtra = 0; Зарезервированное поле. Обнуляем. wcl.hbrBackground = (HBRUSH)COLOR_WINDOW; Цвет окошка. Константа COLOR_WINDOW приводится к типу HBRUSH (в Delphi приводить не нужно). Также, с помощью функции GetStockObject(), можно задать цвет кисти окна или фоновый рисунок. Теперь, смело, регистрируем класс окна.

RegisterClass(&wcl); В качестве параметра функции RegisterClass передается указатель на структуру wcl.

Следующей строкой мы создаем наше окно.

hMainWnd = CreateWindow(szWinName, "Простое окно на API." , WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ S_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 300, 170, HWND_DESKTOP, NULL, hInstance, NULL);
  • Первый параметр - имя класса окна.
  • Второй параметр - Заголовок окна.
  • Третий параметр - стиль окна. Из стандартного WS_OVERLAPPEDWINDOW, с помощью операции xor, я изъял возможность масштабирования окна и отключил кнопку максимизации.
  • Четвертый и пятый - положение окна от левого, верхнего угла экрана. У меня CW_USEDEFAULT, при этом значении система выбирает положение окна автоматически.
  • Шестой и седьмой параметры - ширина и высота окна, соответственно.
  • Восьмой параметр - окно владелец. У главного окна, владелец - рабочий стол (0). У элементов управления - главное окно.
  • Девятый - указатель на дескриптор меню. Нет меню, нет и указателя.
  • Десятый параметр - Дескриптор текущего экземпляра приложения.
  • Одиннадцатый - Используется при создании приложений с MDI-интерфейсом. Нам не нужен.
Функция возвращает дескриптор созданного окна, который заносится в переменную hMainWnd.
Дескриптор окна - уникальный номер в системе, по которому идентифицируется окно или элемент управления.

Далее мы создадим необходимые элементы управления. Все элементы управления - те же окна, просто они имеют другое имя класса. Классы элементов управления регистрировать не нужно, они уже предопределены в системе. Кнопка - класс button. Поле ввода - класс edit. Надпись - класс ststic. Существует множество классов, которые соответствуют стандартным элементам управления. Контролы создаем с помощью, знакомой нам, функции CreateWindow() и незнакомой CreateWindowEx(). CreateWindowEx() позволяет создать окно с расширенным стилем. Мы используем ее для создания полей ввода. В этой функции добавлен первый параметр, который и задает этот самый расширенный стиль, остальные параметры как у CreateWindow(). Элементы управления являются дочерними окнами, их владелец главное окно.

Создавая контролы, в параметрах функции необходимо указать дескриптор главного окна, а также стиль окна WS_CHILD. Внешним видом и функциональностью элементов управления можно манипулировать с помощью флагов: WS_, ES_, BS_, SS_, объединяя их битовой операцией "или". Создавая контролы, мы инициализируем соответствующие переменные их дескрипторами, которые возвращают функции CreateWindow() и CreateWindowEx(). Эти дескрипторы понадобятся нам для дальнейшей работы с элементами управления. Отображаем, созданное нами, окно на экране и перерисовываем его.

Функция GetMessage выбирает очередное сообщение из очереди сообщений приложения и отправляет его окну.
  • Первый параметр - структура типа MSG (в Delphi типа TMSG)
  • Второй параметр - дескриптор окна, которому предназначено сообщение. Если NULL или 0, то все окна приложения.
  • Третий и четвертый - позволяют задать диапазон принимаемых сообщений. Если 0, то все сообщения, адресованные окну.
GetMessage - возвращает FALSE при появлении сообщения WM_QUIT, в этом случае происходит выход из цикла и приложение завершает работу. TranslateMessage - переводит виртуальные коды клавиш в клавиатурные сообщения. DispatchMessage - отправляет сообщение оконной функции, для обработки.

Оконная функция обеспечивает функциональность программы, путем обработки системных сообщений. Оконная функция является CALLBACK - функцией, т.е. вызывается операционной системой в ответ на поступившее, новое сообщение. Оконная функция объявлена таким образом:

LRESULT CALLBACK WindowFunc(HWND hMainWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

  • HMainWnd - дескриптор главного окна.
  • iMsg - номер сообщения. Смотри константы WM_.
  • lParam и wParam - параметры сообщения.

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

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

Внутри оконной функции расположен оператор выбора, который и выполняет вышеописанную задачу. В операторе выбора обязательно должен быть организован обработчик по умолчанию, который реализуется функцией DefWindowProc(hMainWnd, iMsg, wParam, lParam);

Если этого не сделать, наша программа издохнет так и не ожив. Множество сообщений, обрабатывается самой системой, такие как: изменение размеров окна, сворачивание/разворачивание окна, вызов системного меню etc. Для этого и служит DefWindowProc().

При работе с оконными элементами управления, окну владельцу посылается сообщение WM_COMMAND, при этом lParam содержит дескриптор элемента управления, а старший байт параметра wParam - идентификатор события, вызванного в элементе управления. Например: при нажатии на кнопку - BN_CLICKED. Смотри константы BN_, WM_. Закрыть прогу мы можем использовав функцию PostQuitMessage(0). Эта функция посылает окну сообщение WM_QUIT.

Несколько слов о том, как писать такие программы на Delphi. Создаем новый проект, запускаем Project Manager, удаляем Unit1 вместе с формой. Жмем Ctrl + F12 и открываем файл проекта. Удаляем из uses модуль forms, добавляем туда windows и messages. Удаляем все между begin и end. Заготовка готова. Можно кодить. Писать программы на чистом API невозможно без справки, которая всегда должна быть под рукой. Будь ты самим Гейтсом - все не запомнить. Рекомендую:

  • прежде всего - MSDN ;
  • справочная система Delphi (файл MSTOOLS.HLP);
  • на сайте http://www.soobcha.ru/rushelp есть русская справка по Win32 API.
Вот и все.
Удачи.

Бобаченко Максим Скачать: CreateWnd.zip (2.6 K)
архив содержит файлы windows.cpp и windows.dpr

Разработка графического интерфейса

Ключевым средством взаимодействия пользователя с программой является графический пользовательский интерфейс (Graphical User Interface, GUI). GUI любого программного продукта является одним из ключевых факторов его популярности.

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

На практике программирование Windows-приложений предполагает экстенсивное использование различных инструментальных средств и мастеров. Таким образом, учитывая стандарты выбранной операционной системы, программное средство будет иметь оконный интерфейс. Это обусловлено, прежде всего, тем, что окна являются основными элементами графического интерфейса в операционных системах (ОС) семейства «Windows». Они представляют собой прямоугольные области, которые имеют свои настройки, свойства и типы .

Графическая часть обучающего блока включает в себя окна четырех типов:

Главное окно -- содержит все элементы навигации по программе, а также дополнительную информацию, необходимую для удобства работы с ПС;

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

Окна работы с программными возможностями -- обеспечивают работу с основными функциями обучающего блока, такими как прохождение тестов и изучение лекций;

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

Главное окно программы будет содержать следующие элементы управления и вывода информации:

Заголовок окна, который содержит название программы и назначение окна;

Кнопки системного меню, которые отвечают за изменение размера, минимизацию и закрытие программы;

Область названия окна, которая носит исключительно функцию украшения и необходима для соответствия общему дизайн-решению;

Область приветствия;

Область вывода дня недели, текущей даты и времени;

Пользовательская панель инструментов, содержащая кнопки для доступа к основным функциям программы;

Административная панель, включает в себя кнопку для доступа к административным элементам управления ПС;

Строка состояния, отображающая информацию обо всех режимах работы программы.

Схема главного окна графического интерфейса (вид окна для административной учетной записи) представлена на рисунке 3.2

Рисунок 3.2 -- Схема главного окна графического интерфейса: 1 -- заголовок окна; 2 -- кнопки системного меню; 3 -- область названия окна; 4 -- строка состояния; 5 -- область приветствия; 6 -- область вывода дня недели, даты и времени; 7 -- административная панель; 8 -- пользовательская панель; 9 -- кнопка для доступа к стадии обучения; 10 -- кнопка для доступа к стадии тестирования; 11 -- кнопка для вывода статистики и графиков; 12 -- выход; 13 -- кнопка для доступа в административную часть приложения

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

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

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

Статистика пользователя реализована в виде графиков, которые выстраивается в зависимости от полученных им результатов. Для каждого теста выстраивается своя динамика. Графики содержат все необходимые подписи, реализованы с помощью компонента TChart, в связи с чем имеют массу элементов управления, которые встроены в компонент по умолчанию и как следствие реализованы в приложении.

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

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