EuWinGUI → 

Материал из Вавилон.wiki

Перейти к: навигация, поиск
Реклама на сайте


Тут можно разместить свою рекламу !
Эта страница является заготовкой, требующей доработки.

Библиотека EuWinGUI

GUI библиотека-оболочка для Win32 приложений Euphoria. Базируется на оригинальной WinGUI C++ библиотеке.

(C)2001-2006 by Andrea Cini.

Содержание

[править] Введение

EuWinGUI предоставляет простой способ создания 32-битных приложений Windows GUI ANSI с помощью Euphoria.

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

[править] Что это?

EuWinGUI это не клон Win32Lib, не его урезанная версия и не заменяет эту библиотеку, которая остается наиболее полным дополнением для программирования под Win32 на Euphoria.

EuWinGUI создана полностью с нуля и является прямым переводом на язык Euphoria ранних версий моей WinGUI библиотеки для C++. EuWinGUI - перевод версии 1.5.0 оригинальной WinGUI библиотеки для C++ (которая сейчас достигла версии 4.0.0, около 10000 строк исходного кода, имеет улучшенную обработку событий, полная поддержка сабклассинга, более 50 различных типов элементов управления и другие возможности), с некоторыми недостатками ранних версий и упрощениями, необходимыми, чтобы сделать код как можно более компактным.

Я начал писать оригинальную WinGUI библиотеку для C++ потому что мне нужен был royalty-free GUI каркас для моих программ, который был бы достаточно "легким", чтобы использовать его для очень маленьких приложений без необходимости распространения вместе с ними дополнительных коммерческих (часто очень больших) dll-библиотек.

В то же время, я решил портировать на Euphoria ранние версии моей C++ библиотеки, потому что мне кажется, что Win32Lib стала слишком большой для использования в простых GUI приложениях и слишком сложной, чтобы изучаться новичками в программировании под Windows. EuWinGUI во много раз меньше чем другие существующие библиотеки, а также может свободно распространяться с вашими приложениями.

Конечно, EuWinGUI не такая мощная как Win32Lib, но она становится полезной, когда вам нужно создать приложение с простым GUI фронт-эндом, а используя Win32Lib вы получаете слишком "тяжелый" и чрезмерно усложненный результат. Возможно вы будете удивлены тем возможностям, которые предоставляет эта маленькая библиотека, и, я надеюсь, вы ее опробуете.

Код EuWinGUI не совместим с Win32Lib, потому что он является переводм оригинальной WinGUI библилиотеки для C++, которая не имеет ничего общего с Win32Lib, но так как она сделана с использованием ограниченного набора функций и процедур, возможный перевод с/на Win32Lib не должен оказаться слишком сложным.

В некоторых случаях часть EuWinGUI/WinGUI функций даже имеют те же самые имена, что и похожие функции Win32Lib; так произоходит потому, что часто эти имена происходят прямо от имен оригинальных Windows API функций, и с точки зрения программиста проще использовать их, чем каждый раз изобретать совершенно новые имена....

Конечно, EuWinGUI распространяется вместе с её собственной средой разработки (которая использует эту же библиотеку), Designer.exw. Designer позволяет визуально создавать интерфейс вашей программы и генерирует базовый код Euphoria, необходимый чтобы построить его.

[править] Отказ от отвественности и распространение

The EuWinGUI library is completely FREE for use and for shipping with your personal or commercial Euphoria applications. You are allowed to distribute the Euphoria applications created with the EuWinGUI wrapper ".ew" library(ies) AND the EuWinGUI.dll in either open/free or closed/commercial forms. I just ask you to add somewhere to the documentation of your EuWinGUI programs that they use "The EuWinGUI Library by Andrea Cini", or something similar.

The EuWinGUI library/package is ONLY released to be used for Euphoria programming. You are only allowed to use the EuWinGUI.dll with Euphoria-created applications. You are NOT allowed to create or distribute wrapper or import libraries for the EuWinGUI.dll with any other languages than Euphoria or to use the EuWinGUI.dll with any other languages than Euphoria without a written permission of the Author.

THOUGH VERY WELL TESTED, BEING RELEASED AS FREEWARE, THE EuWinGUI LIBRARY COMES WITH NO WARRANTIES OF ANY KIND. USE IT AT YOUR OWN RISK OR DO NOT USE IT. THE AUTHOR OF THIS LIBRARY CANNOT BE HELD RESPONSIBLE FOR ANY DAMAGE CAUSED BY THE PROPER OR IMPROPER USE OF THIS LIBRARY OR OF THE APPLICATIONS WHICH USE IT (etc. etc. etc..........)

The original WinGUI Library for C++
The EuWinGUI Library for Euphoria
All included demos, images, icons and the Window Designer
(C)2001-2006 by Andrea Cini.
eMail: andrea_cini@katamail.com

Библиотека EuWinGUI полностью СВОБОДНА для использования и распространения с вашими персональными или коммерческими приложениями на Euphoria. Разрешается распространять приложения на Euphoria, созданные с использованием EuWinGUI ".ew" библиотеки (библиотек) И EuWinGUI.dll в открытых/свободных или закрытых/коммерческих формах. Я только прошу вас добавить где-то в документации ваших EuWinGUI программ, что они используют "EuWinGUI библиотеку созданную Andrea Cini", или что-то в этом роде.

Библиотека/пакет EuWinGUI создан ТОЛЬКО для использования в программировании на Euphoria. Разрешено использовать EuWinGUI.dll только с приложениями на Euphoria. НЕ разрешено создавать и распространять оболочки или импортирующие библиотеки для EuWinGUI.dll с помощью любых других языков программирования или для использования EuWinGUI.dll с любым языком программирования, кроме Euphoria, без письменного разрешения Автора.

ХОТЯ БИБЛИОТЕКА EuWinGUI ОЧЕНЬ ХОРОШО ПРОТЕСТИРОВАНА, ИЗДАНА КАК FREEWARE, ОНА РАСПРОСТРАНЯЕТСЯ БЕЗ ЛЮБОГО ВИДА ГАРАНТИЙ. ИСПОЛЬЗУЙТЕ ЕЁ НА СВОЙ РИСК ИЛИ НЕ ИСПОЛЬЗУЙТЕ ЕЁ. АВТОР ЭТОЙ БИБЛИОТЕКИ НЕ НЕСЕТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБОЙ УЩЕРБ, ВЫЗВАННЫЙ ПРАВИЛЬНЫМ ИЛИ НЕПРАЛВИЛЬНЫМ ИСПОЛЬЗОВАНИЕМ БИБЛИОТЕКИ ИЛИ ПРИЛОЖЕНИЙ, ИСПОЛЬЗУЮЩИХ ЕЁ (и так далее, и тому подобное..........)

Оригинальная WinGUI библиотека для C++
EuWinGUI библиотека для Euphoria
Все включенные демонстрационные программы, изображения, значки и Window Designer
(С)2001-2006 Andrea Cini
eMail: andrea_cini@katamail.com

[править] Установка EuWinGUI

Установить библиотеку EuWinGUI очень легко: просто распакуйте архив EuWinGUI.zip в главную директорию Euphoria, сохраняя структуру папок. Так EuWinGUI.dll и значок попадут в папку ...Euphoria\Bin\, библиотеки EuWinGUI.ew и EWGUties.ew попадут в ...\Euphoria\Include\ директорию, и будет создано три дополнительных папки ("EWG-Docs", "EWG-Demos" and "EWG-Designer"), содержащие документацию библиотеки, демо-программы и Window Designer. Вы можете переместить эти три новые папки куда вам захочется.

Установка позволит вам запускать, связывать или компилировать любые программы, включенные в пакет, а строка "include EuWinGUI.ew" или "include EWGUties.ew" в начале кода вашего приложения позволит вам использовать все функции, процедуры и переменные, описанные ниже.

На случай если вы собираетесь распространять вашу скомпилированную/связанную программу, просто не забудьте передавать EuWinGUI.dll вместе с ней.

[править] Как это работает - простой пример

В EuWinGUI вам не нужно иметь дело со сложностями Windows API программирования. В основном, чтобы взаимодействовать с вашей программой, вам будет достаточно проверить текущие значения двух глобальных атомов (Event ("событие") и EventOwner ("получатель события")), которые позволяют вам определить "сделал" ли и как "сделал" пользователь с интерфейсом вашего приложения.

Хороший пример будет лучше тысяч слов. Ниже находится код примера (менее 20 строк) приложения EuWinGUI' ("Button.exw", находящегося внутри папки "Demos" пакета). Он показывает окно с кнопкой по центру. При клике левой кнопкой мыши по кнопке, появляется окошко с сообщением.

include EuWinGUI.ew
atom button1

procedure EventLoop()

while True do

  WaitEvent()

  if Event = Click then
     if EventOwner = button1 then
     InfoMsg("Programmed in Euphoria with the EuWinGUI Library!!","EuWinGUI")
     end if
  end if

end while

end procedure

procedure WinMain()

  Window("EuWinGUI - The First Program",100,100,290,95)
  button1 = Control(Button,"Info",5,10,270,50)

  SetIcon("EuWinGUI.ICO")

  EventLoop()
  CloseApp(0)

end procedure

WinMain()

Давайте рассмотрим код.

  • Выражение include подключает библиотеку EuWinGUI к программе, точно так же как любую другую библиотеку Euphoria;
  • atom button1 будет служить для хранения идентификатора одного элемента управления, простой кнопки. Если бы нужно было больше элементов управления, мы бы добавили больше переменных, по одной на элемент управления;
  • procedure EventLoop() это центральная часть нашей системы. Внутри процедуры мы будем проверять какое "событие" (то есть действие, созданное взаимодействием пользователя с интерфейсом программы) произошло с приложением: программа будет (и должна) продолжить выполнение этой процедуры до завершения, поэтому не используйте выражение "return" в процедуре, если (и пока) вы не хотите завершить вашу программу;
  • while True do говорит, что код внутри цикла проверки событий будет выполняться продолжительное время; это эквивалентно повторному вызову EventLoop() в конце кода проверки события, но рекурсия в Euphoria может привести к переполнению стека, поэтому в данном случае бесконечный цикл будет более эффективен;
  • процедура WaitEvent() - одна из важнейших во всей библиотеке. Она передает управление Windows и не возвращает его, пока не произойдет какое-нибудь "событие". Как только происходит событие, процедура присваивает глобальному атому Event тип произошедшего события, и глобальному атому EventOwner идентификатор элемента управления, которому оно принадлежит, потом возвращает управление. При помощи проверки значений Event и EventOwner после выхода из процедуры вы сможете узнать какое и с каким элементом произошло событие (какие события доступны для различных типов элементов управления смотрите ниже);
  • строка if Event = Click then проверяет, является произошедшее событие кликом левой кнопкой мыши;
  • строка if EventOwner = button1 проверяет, произошло ли это событие (клик) с кнопкой. При положительном ответе, при помощи EuWinGUI процедуры InfoMsg() (эквивалентной функции Euphoria "message_box()", но более простой в использовании) показывается информационное сообщение;
  • как только событие, которое нас интересует (левый клик мышью по кнопке с надписью "Info") будет обработано, конечная строка end while заставит код проверки запуститься заново, и так пока программа не завершит работу; в нашем случае это произойдет при закрытии пользователем окна программы, но возможно завершить приложение EuWinGUI в любой момент, просто выйдя из процедуры EventLoop(), используя выражение return;
  • внутри процедуры WinMain() мы строим интерфейс нашей программы (главное окно и дочерние элементы управления на нем), при необходимости назначаем созданным элементам управления какие-то конкретные значения, и, наконец, вызываем процедуру EventLoop() чтобы начать проверку событий;
  • Window() - процедура, с которой начинается создание интерфейса программы. Она создает главное (и единственное) окно с заданным заголовком (в нашем случае, "EuWinGUI - The First Program"), позицией на экране (у нас 100, 100) и размерам (290 пикселей в ширину и 95 в высоту). Мы не можем добавлять элементы управления, до вызова этой процедуры. Как только окно создано, процедура присваивает глобальному атому WinHwnd значение идентификатора созданного главного окна и возвращает управление. Значение WinHwnd позже будет использовано как идентификатор главного окна в каждой функции или процедуре EuWinGUI, в которой требуется этот параметр;
  • строка button1 = Control(Button,"Info",5,10,270,50) вызывает функцию Control(). Эта функция создает новый элемент управления выбранного типа (см. ниже список доступных типов элементов управления), с выбранной надписью, позицией (относительно клиентской области окна) и размерами, и возвращает идентификатор созданного элемента управления. Этот идентификатор может быть использован в любой функции EuWinGUI, которой нужен будет этот параметр. Эта функция может быть использована только после вызова процедуры Window();
  • процедура SetIcon() устанавливает значок в заголовке главного окна и на панели задач Windows. По умолчанию приложение EuWinGUI использует значок Euphoria или тот, который использовался при связывании программы;
  • EventLoop() вызывает описанную ранее процедуру, которая запускает цикл проверки событий;
  • процедура CloseApp(0) закрывает приложение, как только происходит выход из процедуры EventLoop(), освобождая все ресурсы, которые были использованы EuWinGUI во время выполнения. Если программа EuWinGUI будет закрыта без вызова этой процедуры (например при помощи вызова стандартной процедуры abort()), память используемая ресурсами приложения не будет освобождена и больше не будет доступна системе, поэтому нужно вызывать CloseApp(0) перед выходом из программы. Если выйти из приложения закрытием главного окна и значение глобального атома CloseEventEnabled будет равно False (значение по-умолчанию), EuWinGUI освободит память автоматически, но если переменная CloseEventEnabled будет равна True и/или будут предоставлены дополнительные способы закрытия программы (например кнопка "Close" в демо-программе "TwoButtons.exw"), то для закрытия программы нужно использовать процедуру CloseApp();
  • наконец, WinMain() запускает главную процедуру программы.

Другие демонстрационные программы показывают более сложные примеры приложений EuWinGUI.

[править] Многооконные приложения EuWinGUI

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

Чтобы создать новое пустое дочернее окно после создания главного, достаточно вызвать функцию Control(), использую Dialog в качестве первого параметра. Возвращенное функцией число - идентификатор созданного дочернего окна, который может быть использован с любыми функциями/процедурами, в которых он потребуется.

Дочерние окна создаются в стиле, выбранном в глобальной переменной WindowType, точно так же, как это было при вызове процедуры Window(), поэтому можно создавть дочерние окна других стилей, изменяя значение переменной WindowType перед вызовом функциии Control().

После этого процедура SetParentWindow() устанавливает одно из существующих окон (главное или одно из диалоговых) как "материнское" для всех элементов управления, созданных после этого функцией Control(), и так пока новый вызов процедуры SetParentWindow() не изменит "материнское" окно.

Помните, что независимо от значения идентификатора, переданного процедуре SetParentWindow(), диалоговые окна не независимы, а всегда являются дочерними по отношению к главному окну, а это значит, что если диалоговое окно пересекается с главным, то последнее будет частично или полностью перекрыто диалоговым окном. Если нужно создать многооконное приложение, с окнами, всегда видимыми при их активации, есть очень простая техника, описанная в разделе "Часто задаваемые вопросы", которая позовляет решить эту проблему тремя дополнительными строками кода.

Единственное, что нужно помнить, используя диалоги - это то, что пока переменная CloseEventEnabled имеет значение True, если пользователь закрывает диалоговое окно, то закрывается все приложение, как если бы было закрыто главное окно. Чтобы избежать этого, достаточно присвоить глобальной переменной CloseEventEnabled значение True и при обработке события Close (закрытие) диалогов делать их невидимыми при помощи вызова SetVisible() вместо закрытия всего приложения.

См. также примеры многооконных приложений в папке с демо-программами.

[править] Выполнение длительных фоновых операций

Я получил много вопросов, есть ли в EuWinGUI способ выполнять длительные фоновые операции, при этом продолжая обрабатывать события генерируемые взаимодействием пользователя с интерфейсом программы. Обычно, когда начинается длительная операция, фактически программа перестаёт отвечать ни на какие события, так как занята другой работой, и код обработки событий не запускается, пока операция не будет закончена и работа программы не вернется в нормальное состояние. Это значит не только, что все события, сгенерированные пока программа была занята, не будут обработаны, но и то, что низкоуровневая обработка события внутри библиотеки на стороне операционной системы будет приостановлена, что приведет к тому, что приложение будет буквально "заморожено".

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

С более ранними версиями библиотеки так делать было достаточно сложно, но теперь это проще, благодаря двум новым подпрограммам: IsEventWaiting() и ProcessEvent().

IsEventWaiting() проверяет наличия любых событий (высокоуровневых или низкоуровневых, обрабатываемых внутри библиотеки), ожидающих обработки и возвращает True при их наличии. ProcessEvent() - практически копия функции WaitEvent(), с одним важным отличием: WaitEvent() устанавливает значения глобальных переменных Event/EventOwner/EventItem и возвращает управление ТОЛЬКО при поступлении события EuWinGUI; ProcessEvent() наоборот, устанавливает глобальные переменные и возвращает управление даже если нет событий, ожидающих обработки (в этом случае переменным Event/EventOwner/EventItem присваивается значение 0). В основном это значит, что теперь возоможно обрабатывать события как обычно, или, с другой стороны, выполнять часть длительной операции, пока значение Event равно нулю, то есть пока нет событий, ожидающих обработки.

Две прогаммы в папке "Demos", "Bricks.exw" и "CDChecker.exw", показывают как создавать приложения, которые могут отвечать на любые события во время выполнения длительной операции (см. комментарии в коде, а также файл "Demos.txt" для получения дополнительной информации).

Первая программа - игра, и её "длительная работа" состоит в непрерывном рисовании окна для обновления позиций "спрайтов". Так как требуется скрывать курсор мыши, когда он двигается над игровым окном, чтобы избежать покрытия двигающегося шарика или одного из блоков, нужно было в конце каждого цикла рисования проверять, нет ли событий ожидающих обработки. Если IsEventWaiting() возвращает True, вызывается ProcessEvent(), чтобы установить значения главных переменных Event, EventOwner и EventItem, и выполняется код обработки (например, если произошло событие мыши, курсор делается невидимым), а потом снова выполняется цикл рисования, и т.д.

Вторая прогамма - утилита, и её "длительная работа" состоит в чтении двух или более файлов с диска и проверке, являются они идентичными. Так как файлов может быть много и/или они могут быть очень большими, их проверка может занять несколько минут непрерывной работы. В этом случае для пользователя очень важна возможность прерывания операции или открытия/закрытия окна отчета с деталями процесса сравнения. Чтобы позволить приложению отвечать на нужные события, проверяющая подпрограмма написана так, что за один раз для сравнения считывается небольшая часть исходного и резервного файлов, после чего используются IsEventWaiting() и ProcessEvent(), чтобы узнать, нет ли ожидающих обработки событий, и обработать их (в данном случае, это возможно зафиксированные клики на кнопке прекращения и окне отчета) перед чтением следующего блока байтов, и так далее, пока файлы не будут полностью прочитаны.

Кто-то может спросить, зачем тогда нужна процедура WaitEvent(), если ProcessEvent() делает ту же самую, если не большую, работу. Ответ состоит в том, что WaitEvent() намного более эффективна в программах, не требующих специального метода обработки, чем ProcessEvent(), и когда нет ожидающих событий, входит в "эффективный цикл ожидания", который потребляет очень мало системных ресурсов и процессорного времени. ProcessEvent() - наоборот, "занятая" функция (потому что всегда немедленно возвращает управление, даже если нет ожидающих событий), что значительно увеличивает нагрузку процессора и системных ресурсов (поэтому понижает производительность других запущенных приложений), даже когда они не очень нужны. По этой причине описанные демо-программы для улучшения производительности используют оба варианта: WaitEvent() используется в нормальном цикле обработки событий, когда приложение простаивает, ProcessEvent() - наоборот, когда начата основная работа программы.

[править] Как насчет графики?

Хотя в оригинальной библиотеке WinGUI для C++ реализован почти весь список графических функций и процедур, в версии для Euphoria намеренно включены только несколько, чтобы оставить размер библиотеки как можно меньшим, тем более что большинство из них редко используются в небольших приложениях.

Тем не менее, чтобы дать EuWinGUI лучшую модульность и позволить использовать её без ограничений или вместе с другими графическими библиотеками, WinGUI процедура SetDrawingProc() была переведена на Euphoria вместе с базовым набором графических подпрограмм, который позволяет решать большинство обычных графических задач.

Прежде всего нужно сказать, что приложение EuWinGUI может использовать одни и те же графические функции при рисовании двумя различными способами: прямо на поверхности элемента управления, для чего сначала используется SetDrawingControl() чтобы указать элемент управления, на котором вы собираетесь рисовать, или рисование в памяти и последуюее копирование изображения из памяти на элемент управления, в этом случае сначала используется SetDrawingMB() чтобы выбрать область памяти, где вы собираетесь рисовать.

Первый способ (изначально реализованный в EuWinGUI) полезен, когда существующему элемету управления нужно добавить неподвижные графические элементы (см. "ListView.exw" демо, где это было использовано, чтобы добавить сетку всем спискам), но не очень легко обрабатывать из-за того, как работает операционная система. Те, кто знаком с программированием через API, знают что можно свободно рисовать на поверхности окна или элемента управления, использую несколько различных функций GDI. Проблема в том, что операционная система автоматически "заботится" о визуальных аспектах всех окон и элементов управления, поэтому все что нарисовано пользователем автоматически стирается каждый раз, когда окно или элемент управления обновляется (т.е. стирается и перерисовывается), поэтому приходится каждый раз перерисовывать после таких обновлений (именно поэтому пользователи Win32Lib помещают свои графические инструкции внутри процедур, вызываемых по событию onPaint).

EuWinGUI не перехватывает событие "Paint", как это делают обычно, а использует процедуру SetDrawingProc(), чтобы указать адрес произвольной процедуры (содержащей инструкции, нужные для рисования на поверхности окна или элемента управления), которая выполняется каждый раз, когда окно или элемент управления перерисовывается операционной системой, делая нарисованное "устойчивым".

Очевидно, что этот метод не подходит, когда рисунок очень сложен, изменяется со временем или должен быть анимированным. Во всех этих случаях используется более практичное решение - второй метод реализованный в EuWinGUI, рисование в памяти и последующее копирование рисунка на элемент управления Picture. Как только рисунок в памяти связан с элементом управления Picture, функция обновления рисунка становится не нужной, так как эта задача автоматически выполняется операционной системой. Рисунок в памяти может быть пустым, созданным непосредственно в памяти функцией NewMB(), или это может быть рисунок, загруженный из файла с помощью функции LoadPic(); в обоих случаях, идентификатор нового рисунка, созданного или загруженного, может быть использован в функции SetDrawingMB(), чтобы установить его активным рисунком, на котором будут рисовать все графические функции, и может быть закреплен за элементом управления класса Picture с помощью функции SetPic(). Излишне говорить, что если рисунок загружен из файла на диске, рисование на этом рисунке НЕ изменяет файл на диске, а ТОЛЬКО его копию в памяти, созданную функциещ LoadPic(). Возможно также копировать часть изображения в другое изображение с помощью процедуры CopyMB(), а также можно копировать часть изображения прямо на поверхность элемента управления с помощью <copy>CopyMBToControl()</copy>. Втрая функция очень полезна, так как она позволяет копировать рисунок немедленно на элемент управления, не дожидаясь, пока операционная сисмема очистит и перерисует его, таким образом избегая мигания изображения в играх или анимациях. Эта техника рисования графики в памяти и последующее немедленное копирование на элемент управления для обновления обычно называется "двойной буферизацией" и используется в демо-игре Bricks.exw и утилите CDChecker.exw (для симуляции индикатора выполнения), включенных в пакет. Вы можете представить рисунок в памяти (созданный или загруженный) как невидимую доску для рисования, на которой можно свободно рисовать и где рисунок всегда устойчив, которая становится видимой только когда закреплена за элементом управления класса Picture с помощью SetPic() или непосредственно копируется на элемент управления функцией CopyMBToContol().

[править] Печать с помощью EuWinGUI

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

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

Как только принтер выбран, можно создавать "печатаемый документ". Это делается при помощи функции NewDocument(), которая принимает текстовую строку в качестве имени документа. Имя документа используется только как ссылка и служит только чтобы различить ваш документ в очереди печати принтера. Если указана пустая строка, библиотека по-умолчанию использует имя "Untitled Document".

Печатаемый документ может состоять из любого количества страниц. Когда печатаемый документ только создан, в нем только одна страница, но страницы могут быть добавлены при помощи процедуры NewPage (которая не имеет аргументов). При использовании этой процедуры происходит две вещи: текущая страница "закрывается" и отсылается в буфер принтера, и в документ добавляется новая чистая страница, которая становится новой текущей страницей, к которой будут применяться все последующие инструкции рисования. Помните, что как только страница "закрыта", она становится недоступной, поэтому вы должны организовать процесс печати так, чтобы подготавливать одну страницу за раз, и закрывать ее только когда она полность готова к отправке на печать.

Страницу документа можно представить, как пустое изображение в памяти с определенной шириной и высотой в пикселях (постоянная величина для всех страниц одного документа), которые зависят только от выбранного принтера и его настроек. Ширину и высоту страницы можно узнать при помощи функции GetPageSize(), указывая X_DIM или Y_DIM флаги в качестве аргумента, в зависимости от того, нужно ли вам получить ширину или высоту текущей страницы. Эта функция также может быть использована, чтобы узнать, выбран ли принтер, нулевое значение для ширины и высоты означает, что принтер еще не выбран.

Как только вы узнали размеры страницы, вы может начать "рисовать" текст на текущей странице при помощи процедуры PrintString(), которая работает точно также, как процедура DrawString(), используемая чтобы рисовать текст в памяти. Возможно узнать ширину и высоту напечатанной строки текста при помощи функции GetPrinterStringSize() - похожей на функцию GetStringSize() - так что возможно центрировать строку на странице или правильно вертикально расположить на странице две последовательные строки текста, используя простую арифметику.

Можно установить шрифт и цвет, который будет использован при печати любой строки при помощи функций SetPrinterFont() и SetPrinterPenColor(), точно также, как это делалось при рисовании на изображениях. Конечно, нет никаких ограничений при смешивании цветов и шрифтов, если конечно вы не собираетесь использовать только стандартные системные шрифты (FN_DEFAULT и FN_FIXED), сначала нужно создать все нужные шрифты с помощью функции NewFont().

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

Когда все страницы документа созданы, процедура StartPrinting() полностью закрывает документ и отправляет его на принтер для печати. Как только документ закрыт и отправлен на принтер, с ним уже ничего нельзя сделат программно (конечно пользователь может вручную остановить/прервать печать в окне очереди печати принтера).

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

Например, если создать изображение в памяти и напечатать какой-то текст с использованием стандартного шрифта, а потом напечатать его с помощью PrintMB(), вы заметите, что размеры текста на бумаге будут значительно различаться от размеров этого же текста напечатанного тем же шрифтом с помощью процедуры PrintString(). Так происходит из-за того, что изображения в памяти используют настройки экрана, которые могут отличаться от настроек и возможностей принтера.

Заметьте, что если ширина вашего экрана обычно 1024 или 1280 пикселей, шрина страницы принтера легко достигает 4000; операцинная система подстраивает размеры символов одного и того же шрифта так, чтобы на глаз размеры текста на экране и при печати на бумаге были примерно одинаковы. Поэтому, если вам нужно использовать вместе текст, напечатанный с помощью PrintString(), и текст напечатанный в памяти, соответствие фактических размеров шрифтов, используемых при печати в памяти, и шрифтов, используемых при непосредственной печати на странице документа, зависит от вас.

См. практический пример использования функций печати в демо-программе "Printing.exw".

[править] Вспомогательная библиотека EWGUties.ew

Вспомогательная библиотека EWGUties.ew - недавнее дополнение в пакете и содержит несколько полезных функций, процедур и образцов кода, которые делают создание приложений EuWinGUI более быстрым и легким. Каждая функция и процедура в начале объявления имеет комментарий, объясняющий её назначение, и может быть свободно изменена для лучшего соответствия вашим потребностям. Поскольку EWGUties.ew подключает EuWinGUI.ew, то, чтобы использовать все функции и процедуры EuWinGUI, достаточно подключать EWGUties.ew в начале ваших программ.

[править] Связывание и компилирование приложения EuWinGUI

Нет конкретных инструкций по связыванию или компилированию программ EuWinGUI, просто старайтесь делать имена процедур и функций понятными, если вы используете Euphoria версий старших 3.x.x, так как EuWinGUI использует routine_id().

Приложения EuWingGUI могут быть связаны или скомпилированы при помощи Euphoria версий 2.4, 2.5 или последними открытыми версиями 3.x.x.

[править] Советы и часто задаваемые вопросы

Вопрос: Почему в EuWinGUI доступны только самые общие типы событий?
Ответ: Потому что хотел сделать библиотеку как можно более компактной и простой, поэтому сабклассинг элементов управления блы сведен к минимуму; если требуется что-то более "тяжелое" и мощное, в Euphoria уже есть Win32Lib. По этим же причинам горячие клавиши в EuWinGUI не реализованы напрямую (но легко эмулируются). С другой стороны, можно добавить дополнительные события с помощью таких низкоуровневых процедур и функций как TrapMessage(), Message() и GetTrappedMessage(), но для этого требуется знание WinAPI.

В: Почему доступен только ограниченный набор типов элементов управления?
О: По причинам, указанным выше, реализованы только наиболее часто используемые типы элементов управления. Однако, помните, что с помощью EuWinGUI можно эмулировать некоторые дополнительные типы: индикатор прогресса, "комбо-бокс", строка состояния, список, даже "табы" и более сложные элементы управления могут быть эмулированы из доступных в EuWinGUI (см. демо-программы). Помните, если вам нужно больше готовых элементов управления, лучше использовать Win32Lib, EuWinGUI предназначена для создания более простых приложений.

В: Я создал элемент управления PictureButton, но он пустой, почему?
О: Потому что в него не загружено изображение (BMP). Используйте процудуру SetPicture(), чтобы загрузить существующий BMP в PictureButton как только он создан.

В: Я создал элемент управления ClickPicture или Picture, но в главном окне ничего не появилось, почему?
О: Элементы управления Picture/ClickPicture создаются пустыми (как и Picture/PushButton), и, т.к. у них нет видимых частей, они сначала "невидимы". Чтобы их можно было увидеть, после их создания используйте процедуру SetPicture(), чтобы загрузить изображение BMP в них. Помните, что вне зависимости от размеров, указанных при создании элемента управления (в отличие от Picture/PushButton), размеры будут подогнаны под размеры загруженного изображения после вызова процедуры SetPicture(). Тем не менее, после загрузки изображения вы можете использовать процедуру SetDim() чтобы установить нужные размеры изображения. Помните, что элемент управления может отвечать на события Click только если он видим, т.е. после того как в него будет загружено изображение.


[править] Приложения

[править] Глобальные переменные

Ниже описаны глобальные переменные определенные и используемые EuWinGUI:

[править] atom Event

хранит тип последнего события после выхода из процедуры WainEvent().

[править] atom EventOwner

[править] atom EventItem

[править] atom UserTrap

[править] atom WinHwnd

....

[править] Типы элементов управления

[править] Типы событий

[править] Другие константы EuWinGUI

[править] Ограничения операционной системы

[править] Демонстрационные программы

[править] Благодарности


п·о·р Язык программирования Euphoria
Типы данных object, sequence, atom, integer
еще что-нибудь
...и еще что-нибудь

Проект Euphoria. Ответственный :): User:Insolor

Вам также может быть интересно:
Инструменты