External: Справочное руководство
- 1. Введение
- 2. Hello, World
- 3. Инициализация
- 4. Создание окон и виджетов
- 5. Font, Style
- 6. Callback функции
- 7. Widget - методы
- 8. Создание меню
- 9. Функции
- 10. Печать
- 11. Заключение
- A. Приложения
External - это GUI библиотека для golang, которая для реализации интерфейса использует отдельную программу, GuiServer - см. здесь.
GuiServer написан на Harbour и GUI-библиотеке HwGUI. Я специально это оговариваю, поскольку в дальнейшем буду ссылаться на HwGUI при описании некоторых виджетов.
При старте External запускает GuiServer, если он еще не запущен, и присоединяется к нему. Связь связь эта может осуществляться одним из двух способов по вашему выбору.
- С помощью tcp/ip соединения. При этом используются два tcp/ip порта. GuiServer может работать как на том же компьютере, что и ваше приложение, так и на удаленном - в этом случае запустить его из приложения не удастся, так что он должен быть запущен заранее. По одному порту External отправляет команды GuiServer'у - создание окон, виджетов, всякие действия с ними и пр., по другому - принимает от него сообщения, поступающие при наступлении каких либо событий, нажатия кнопки, например.
- С помощью обычных файлов - используются два файла, логика взаимодействия та же, что и у двух tcp/ip портов в первом варианте.
Начнем, по традиции, с Hello, World. Вот пример простейшей программы, создающей окно с этой надписью:
package main import egui "github.com/alkresin/external" func main() { if egui.Init("") != 0 { return } pWindow := &egui.Widget{X: 100, Y: 100, W: 400, H: 140, Title: "My first GUI app"} egui.InitMainWindow(pWindow) pWindow.AddWidget(&egui.Widget{Type: "label", X: 20, Y: 60, W: 160, H: 24, Title: "Hello, World!" }) pWindow.Activate() egui.Exit() }
Функция Init() запускает GuiServer и присоединяется к нему. InitMainWindow() создает главное окно приложения с заданными параметрами. Метод AddWidget() — добавляет виджет типа label. Activate() — выводит окно на экран и переводит программу в режим ожидания.
Далее рассмотрим эти действия по порядку.
Как я уже говорил, первое, что следует сделать - это запустить GuiServer и присоединиться к нему. Это делает функция Init(sOpt string), которой передается строка параметров, разделенных символом конца строки ( "\n" ). Вот они (приведены значения по умолчанию):
guiserver=guiserver.exe //Имя исполняемого файла GuiServer type=1 //Способ соединения, 1 - по tcp/ip, 2 - файловое соединение dir= //Каталог для файлов (при type=2), по умолчанию - временный каталог file=gs //Префикс имен файлов (при type=2) address=127.0.0.1 //Ip компьютера с GuiServer (при type=1) port=3101 //Порт GuiServer (при type=1) log=0 //Уровень журналирования (0...2)
Если вам надо изменить, например, номер порта и уровень журналирования, вы можете использовать такой вызов Init():
egui.Init("port=4801\nlog=1")
Символ конца строки используется в качестве разделителя, чтобы было удобнее передать в качестве параметра содержимое ini файла:
var sInit string b, err := ioutil.ReadFile("test.ini") if err != nil { sInit = "" } else { sInit = string(b) } if egui.Init(sInit) != 0 { return } // ...
Функция Init() возвращает 0 в случае успешного выполнения, 1 - если соединиться не удалось, и 2 - если протоколы связи вашей версии External и GuiServer отличаются.
Итак, инициализация прошла успешно, теперь мы можем формировать интерфейс программы. В большинстве случаев начать следует с создания главного окна. Это делается посредством вызова функции InitMainWindow(pWindow), которой в качестве единственного параметра передается указатель на предварительно созданную структуру Widget, описывающую окно. Вот объявление этой структуры:
type Widget struct { Parent *Widget Type string Name string X int Y int W int H int Title string Winstyle int32 TColor int32 BColor int32 Tooltip string Anchor int32 Font *Font AProps map[string]string aWidgets []*Widget }
Структура Widget используется для создания окон, диалогов и виджетов, конкретный тип объекта определяется полем Type; для главного окна это "main", для диалога - "dialog", для, например, кнопки, - "button". К описанию полей структуры мы вернемся чуть позже, а пока продолжим разговор о создании окна.
InitMainWindow(pWindow *Widget) создает окно, этот вызов приводит в конечном итоге к вызову на стороне GuiServer функции Windows API CreateWindowEx() или, если мы работаем под Unix/Linux, gtk_window_new().
Для того, чтобы окно появилось на экране, необходимо вызвать еще метод объекта Widget Activate(). GuiServer по получении соответствующей команды вызывает функцию Windows API ShowWindow() и начинает цикл обработки сообщений, в Unix/Linux делается вызов gtk_main(), что, по сути, то же самое. External после отправления команды на GuiServer тоже входит в цикл ожидания сообщений, (он принимает их, как вы помните, от GuiServer через второй порт), поэтому выполнение программы на этом приостанавливается. Следующие после вызова Activate() для главного окна строки программы (точнее, функции, в которой стоит Activate()) будут выполнены только после закрытия окна, обычно это завершение программы.
Для добавления виджетов используется метод объекта Widget AddWidget(pWidg *Widget). Добавить виджет можно в любой другой виджет, но практически нет какого-либо смысла добавлять, например, Edit в кнопку. Виджеты добавляются в окно (главное или диалог), на панель, на Tab. При добавлении в окно вызовы AddWidget() располагаются между InitMainWindow() и Activate(). При необходимости виджеты можно добавлять и в других частях программы при наступлении каких-то событий. Единственным параметром AddWidget() является указатель на соответствующую структуру Widget, содержащую описание нового виджета
4.1 Структура Widget - описание полей
Parent | объект Widget, родительское окно/виджет |
Type | строка, определяющая тип виджета: "main", "dialog", "button", "label" и пр., полный список см. дальше |
Name | строка - идентификатор виджета |
X, Y, W, H | координаты верхнего левого угла окна/виджета, ширина и высота в пикселях |
Title | заголовок окна, надпись на кнопке, т.е., текст отображаемый на виджете |
Winstyle | число, стиль окна/виджета, принятый в Windows API |
TColor, BColor | число, цвет текста и фона, соответственно |
Tooltip | он и есть тултип - строчка текста, появляющаяся при наведении мышки на виджет |
Anchor | якорь, число, определяющее привязку виджета к краям окна при изменении размера окна, подробнее см. в Приложении |
Font | шрифт, объект структуры Font, подробнее см. дальше |
AProps | поле типа map, список дополнительных атрибутов окна/виджета, подробнее см. дальше; |
aWidgets | массив объектов Widget - тех, что включены в состав этого окна/виджета |
В таблице - список типов виджетов (поле Type структуры Widget), поддерживаемых к моменту написания этого руководства.
main | главное окно |
dialog | диалог |
label | стандартный статический текст |
edit | стандартный виджет для ввода/редактирования текста |
button | стандартная кнопка |
check | стандартная check - кнопка |
radio | стандартная радио - кнопка |
radiogr | группа радио-кнопок |
group | прямоугольная рамка для выделения группы виджетов |
combo | стандартный комбобокс |
bitmap | картинка |
line | разделительная линия |
panel | панель (тулбар), на ней можно размещать другие виджеты |
paneltop | панель, прикрепленная к верхней части окна |
panelbot | панель, прикрепленная к нижней части окна (статусбар) |
panelhead | панель - заголовок окна |
ownbtn | нестандартная кнопка |
splitter | сплиттер - ну, вы знаете |
updown | стандартный виджет для редактирования числа с кнопками вверх/вниз |
tree | дерево |
progress | прогресс - бар |
tab | таб с вкладками |
browse | виджет для отображения таблицы данных |
cedit | виджет для редактирования текста с расширенными возможностями |
link | виджет - ссылка |
monthcal | стандартный календарик |
4.3 AProps - дополнительные атрибуты
Поскольку структура Widget - одна для всех типов виджетов, а наборы свойств у виджетов - разные, то помимо свойств, общих для большинства виджетов (координаты, текст, цвета, ...), в структуру включена хэш-таблица (map) AProps, которая содержит свойства/атрибуты, которые вы хотите установить именно для этого виджета. Конечно, вы можете указывать там не всё, что угодно, а только те атрибуты, которые определены для виджетов этого типа. Ниже - список типов виджетов с соответствующими свойствами:
main | Icon: C |
dialog | Icon: C, NoExitOnEsc: L, NoCloseAble: L |
label | Transpa: L |
edit | Picture: C |
check | Transpa: L |
radio | Transpa: L |
combo | AItems: AC |
bitmap | Transpa: L, TrColor: N, Image: C |
line | Vertical: L |
panel | HStyle: C |
paneltop | HStyle: C |
panelbot | HStyle: C, AParts: AC |
panelhead | HStyle: C, Xt: N, Yt: N, BtnClose: L, BtnMax: L, BtnMin: L |
ownbtn | Transpa: L, TrColor: N, Image: C, HStyles: AC, Xt: N, Yt: N |
splitter | Vertical: L, From: N, TO: N, ALeft: AC, ARight: AC, HStyle: C |
updown | From: N, TO: N |
tree | AImages: AC, EditLabel: L |
progress | Maxpos: N |
browse | Append: L, Autoedit: L, NoVScroll: L, NoBorder: L |
cedit | NoVScroll: L, NoBorder: L |
link | Link: C, ClrVisited: N, ClrLink: N, ClrOver: N |
monthcal | NoToday: L, NoTodayCirc: L, WeekNumb: L |
Здесь перед двоеточием - имя атрибута, после - его тип:
- C - строка;
- N - число;
- L - логическое значение (boolean);
- AC - массив строк.
Поскольку AProps имеет тип map[string]string, мы можем значения всех атрибутов указывать только как строки. Поэтому числа берем в кавычки, логические значения указываем как "t" и "f", для массивов строк лучше всего использовать функцию ToString(xParam ...interface{}), например:
AProps: map[string]string{"AItems": egui.ToString("first", "second", "third")}} AProps: map[string]string{"Transpa": "t"}} AProps: map[string]string{"HStyle": "st2", "BtnClose": "true", "Xt": "60"}}
Далее - список атрибутов с комментариями (в скобках - значения по умолчанию):
Icon | |
NoExitOnEsc | Для диалога: не закрывать диалог при нажатии ESC (Нет) |
NoCloseAble | |
Transpa | Прозрачность (Нет) |
TrColor | Цвет прозрачного слоя |
Picture | |
AItems | Для combobox: массив элементов |
Image | |
Vertical | Для линии (line): вертикальная или горизонтальная (Нет) |
HStyle | Стиль - подробнее см. дальше |
HStyles | |
AParts | Для panelbot: массив с размерами (шириной) в пикселях частей панели |
Xt, Yt | x и y координаты для размещения текста |
BtnClose | Для panelhead: показать ли кнопку закрытия окна (Да) |
BtnMax | Для panelhead: показать ли кнопку максимизации окна (Да) |
BtnMin | Для panelhead: показать ли кнопку минимизации окна (Да) |
From, TO | |
ALeft, ARight | |
AImages | |
EditLabel | |
Maxpos | |
Append | Для browse: можно добавлять строчки (Нет) |
Autoedit | Для browse: можно редактировать ячейки (Нет) |
NoVScroll | Без вертикального скролла (Нет) |
NoBorder | Без окантовки (Нет) |
Link | Для link: url ссылки |
ClrVisited | Для link: цвет уже посещенной ссылки |
ClrLink | Для link: цвет ссылки |
ClrOver | Для link: цвет ссылки при наведении мыши |
NoToday | Для monthcal: |
NoTodayCirc | Для monthcal: |
WeekNumb | Для monthcal: |
Как видите, набор атрибутов, которые можно указать в AProps, невелик. На самом деле список атрибутов виджетов HwGUI (и, соответственно, GuiServer) гораздо больше. External позволяет установить все эти атрибуты, не поддерживаемые через AProps, с помощью метода SetParam()
Для работы со шрифтами в External предусмотрена структура Font:
type Font struct { Family string // наименование шрифта (Arial, Serif, ...) Name string // идентификатор шрифта Height int // размер (высота) шрифта Bold bool // жирный Italic bool // наклонный Underline bool // подчеркнутый Strikeout bool // перечеркнутый Charset int16 // 204 - русский }
Поля этой структуры, думаю, в комментариях не нуждаются - это стандартные атрибуты шрифта. Поле Name, как и в структуре Widget, используется для идентификации шрифта в вашей программе: вы сможете найти ранее созданный экземпляр шрифта (указатель на соответствующую структуру Font) с помощью функции GetFont(sName string).
Для создания шрифта используется функция CreateFont(pFont *Font). Она возвращает указатель на структуру Font (ту же, что передается ей в качестве параметра), который можно затем использовать при объявлении структуры Widget с полем Font. Для изменения шрифта виджета - метод структуры Widget SetFont(pFont *Font):
// Создаем шрифт с идентификатором "flbl" egui.CreateFont(&egui.Font{Name: "flbl", Family: "Georgia", Height: 16}) // Создаем шрифт и указываем его как атрибут диалогового окна pFont := egui.CreateFont(&egui.Font{Family: "Georgia", Height: 16}) pDlg := &egui.Widget{Name: "dlg", X: 300, Y: 200, W: 400, H: 260, Title: "Dialog Test", Font: pFont} egui.InitDialog(pDlg) pLbl1 := pDlg.AddWidget(&egui.Widget{Type: "label", X: 20, Y: 10, W: 160, H: 24, Title: "Identifier:"}) // ... // Изменяем шрифт метки на созданный ранее с идентификатором "flbl" pLbl1.SetFont( egui.GetFont("flbl") )
Style (не путать с Winstyle) - это структура, описывающая вневний вид виджета. Она может использоваться для нестандартных виджетов, которые рисуются самим HwGUI: "panel", "paneltop", "panelbot", "panelhead", "ownbtn".
type Style struct { Name string // идентификатор стиля Orient int16 // тип градиента, его направление Colors []int32 // массив цветов для заполнения фона Corners []int32 // массив с радиусами закругления углов, [верхний левый, // верхний правый, нижний правый, нижний левый] BorderW int8 // толщина рамки в пикселях, если не задана - рамка // рисоваться не будет BorderClr int32 // цвет рамки Bitmap string // картинка для заполнения фона }
Главным образом Style используется для создания градиентного фона виджета. Поле Colors - массив цветов градиента, Orient - направление подробнее см. дальше.
Поле Name, как и в структурах Widget и Font, используется для идентификации стиля в вашей программе: вы сможете найти ранее созданный экземпляр стиля (указатель на соответствующую структуру Style) с помощью функции GetStyle(sName string).
Для создания стиля используется функция CreateStyle(pStyle *Style). Она возвращает указатель на структуру Style (ту же, что передается ей в качестве параметра), который можно затем использовать при объявлении структуры Widget в составе хэш-массива AProps. Ключом соответствующего элемента будет HStyle, а значением - идентификатор (Name) структуры Style.
Callback функции (функция обратного вызова) - одно из важнейших понятий в External, это основная часть вашего приложения. В главной функции (main()) вы обычно создаете главное окно, его меню, набор виджетов. После вызова Activate() выполнение программы приостанавливается, она переходит в режим ожидания сообщений от GuiServer, от GUI-элементов вашего окна, вашего интерфейса. Эти сообщения вызывают выполнение callback функций вашего приложения, тех функций, которые вы установили как callback. Это функции, указанные в объявлении пунктов меню (AddMenuItem()), переданные c помощью SetCallBackProc() для обработки того или иного события (нажатия кнопки, потери фокуса ввода, ...), установленные для вызова после закрытия стандартного диалога (MsgInfo(), SelectFile(), ...), ...
Спецификация callback функции имеет вид func([]string) string, т.е. она принимает в качестве параметра массив строк и возвращает строку. В функциях, которые предназначены для передачи на GuiServer информации о callback функции, используются для этого два параметра: fu func([]string) string и sCode string. Первый - та самая callback функция, второй - идентификатор этой функции (это может быть имя функции или любая другая уникальная строка). External строит хэш-массив map[string]func([]string) string и передает на GuiServer строковый идентификатор. GuiServer при наступлении соответствующего события этот идентификатор возвращает, External находит по нему нужную функцию в хэш-массиве и выполняет ее. Вот так это и работает. Идентификатор нужен для того, чтобы передавать его на GuiServer и обратно - как, например, имя (sName) структур Widget, Font и пр. Кроме функции и ее идентификатора может передаваться произвольное количество строковых параметров - они будут потом переданы обратно callback - функции.
Вот как это может выглядеть в программе:
... // Передается ссылка на объявленную в программе функцию fu1 egui.AddMenuItem("Date", 0, fu1, "fu1" ) ... // Анонимная Callback функция, "Bye...1" - параметр, который она получит в массиве egui.AddMenuItem("Set text to label", 0, func(p []string) string { egui.Widg("main.l1").SetText(p[1]); return "" }, "fsett2", "Bye...1") ... // Callback функция fsett1, которая будет вызвана при нажатии pButton pButton.SetCallBackProc("onclick", fsett1, "fsett1", "first parameter")
При вызове callback функции из меню первым элементом в передаваемом обратно параметре-массиве всегда будет строка "menu", при вызове от какого-либо виджета - идентификатор этого виджета. Т.е., в приведенном выше примере в функции fu1(p []string) массив p будет содержать единственный элемент "menu", а в функции fsett1 - два элемента: идентификатор pButton (sName) и строка "first parameter".
Кроме функции, объявленной в вашем приложении, можно также использовать в качестве callback функции программный код, написанный на Harbour. Для этого вместо функции указываете nil, а вместо ее идентификатора - строку кода. В этом случае событие обрабатывается на GuiServer и в ваше приложение ничего не передаётся:
... // Вызов Harbour/HwGUI функции hwg_EndWindow(), которая закрывает главное окно egui.AddMenuItem("Exit", 0, nil, "hwg_EndWindow()") ... // В 1-ую часть нижней панели (panelbot) главного окна пишется текущая дата pButton.SetCallBackProc("onclick", nil, "hwg_WriteStatus(HWindow():GetMain(),1,Dtoc(Date()),.T.)")
В External есть набор функций, вызывающих стандартные диалоги - информационные, выбора файла и пр. При вызове этих функций можно, а в тех случаях, когда вам требуется результат от диалога, необходимо указать функцию - получатель сообщения о закрытии диалога, т.е., callback функцию. Возьмем, например, диалог выбора цвета:
func fsele_color(p []string) string { // Функция первоначально вызывается из главного меню if p[0] == "menu" { egui.SelectColor(0, fsele_color, "fsele_color", "mm1") } else if p[0] == "mm1" { // Функция была вызвана после закрытия диалога и первым параметром передана метка "mm1" // Второй параметр - выбранный цвет iColor, _ := strconv.Atoi(p[1]) egui.Widg("main.l1").SetColor(int32(iColor), -1) } return "" }
Здесь функции SelectColor(iColor int32, fu func([]string) string, sFunc string, sName string) переданы те же параметры fu и sCode (fsele_color, "fsele_color"), определяющие callback функцию и параметр sName ("mm1") - метка, идентифицирующая источник вызова callback функции - он передается ей первым в массиве строк - параметров. Вторым в данном случае передается значение выбранного цвета.
Если вызова callback функции при закрытии диалога не требуется, соответствующие параметры оставляйте пустыми:
egui.MsgInfo("Some message", "Title", nil, "", "")
Activate() bool | Активирует главного окно или диалог |
Close() bool | Закрывает главное окно или диалог |
AddWidget(pWidg *Widget) *Widget | Добавляет виджет |
SetText(sText string) | Устанавливает текст виджета |
SetImage(sImage string) | Для виджета "bitmap" - изменить картинку, в качестве параметра передается путь и имя файла изображения |
SetParam(sParam string, xParam interface{}) | Устанавливает значение xParam атрибута sParam. Атрибуты sParam - это переменные объекта соответствующего виджета HwGUI. |
GetText() string | Возвращает текст виджета |
SetColor(tColor int32, bColor int32) | Устанавливает цвет текста и фона виджета |
SetFont(pFont *Font) | Устанавливает шрифт виджета |
SetCallBackProc(sbName string, fu func([]string) string, sCode string, params ...string) |
Устанавливает callback процедуру для виджета, sbName - идентификатор события, для которого устанавливается процедура, подробнее о callback функциях см. выше. |
SetCallBackFunc(sbName string, fu func([]string) string, sCode string, params ...string) |
Устанавливает callback функцию для виджета, sbName - идентификатор события, для которого устанавливается процедура, подробнее о callback функциях см. выше. |
Move(iLeft, iTop, iWidth, iHeight int32) | Перемещает виджет и/или изменяет его размер |
Enable(bEnable bool) | Enable или Disable виджет, в зависимости от параметра bEnable |
Hide(bHide bool) | Спрятать или показать виджет - в зависимости от параметра bHide |
Главное меню программы создается между вызовами InitMainWindow() и Activate(), для этого используются функции Menu(sTitle string), EndMenu(), AddMenuItem(sName string, id int, fu func([]string) string, sCode string, params ...string), AddMenuSeparator(). Фигурные скобки после Menu() необязательны, они добавлены здесь для большей выразительности.
package main import ( "time" egui "github.com/alkresin/external" ) func main() { if egui.Init("") != 0 { return } pWindow := &(egui.Widget{X: 100, Y: 100, W: 400, H: 280, Title: "GUI for Golang"}) egui.InitMainWindow(pWindow) // Создание меню начинается с вызва функции Menu("") // с пустым заголовком egui.Menu("") { // Субменю тоже создается с помощью вызова Menu(), // но уже с текстом заголовка egui.Menu("File") { // Добавляем пункт меню // fu1() - callback функция, которая должна выполняться при // выборе этого пункта меню egui.AddMenuItem("Date", 0, fu1, "fu1" ) // Добавляем разделитель egui.AddMenuSeparator() // Здесь в качестве callback-функции указывается Harbour-код, // который будет выполняться на GuiServer. // Здесь это функция, которая закрывает главно окно. egui.AddMenuItem("Exit", 0, nil, "hwg_EndWindow()") } egui.EndMenu() egui.Menu("Help") { egui.AddMenuItem("About", 0, nil, "hwg_MsgInfo(\"My Golang GUI application\"+chr(10)+chr(13)+hwg_version(),\"About\")") } egui.EndMenu() } egui.EndMenu() pWindow.Activate() egui.Exit() } func fu1([]string) string { egui.MsgInfo("Today is " + time.Now().Format("02.01.2006"), "Info", nil, "", "") return "" }
Init(sOpt string) int | Инициализация соединения с GuiServer, подробнее см. здесь |
InitMainWindow(pWnd *Widget) bool | Создает главное окно |
InitDialog(pWnd *Widget) bool | Создает диалоговое окно |
BeginPacket() | Начало пакетной передачи данных |
EndPacket() | Завершение пакетной передачи данных |
WriteLog(sText string) | Добавляет строку в файл egui.log |
GetFont(sName string) *Font | Ищет по имени в списке созданных в программе шрифтов, возвращает найденный указатель на структуру Font |
GetStyle(sName string) *Style | Ищет по имени в списке созданных в программе стилей, возвращает найденный указатель на структуру Style |
Wnd(sName string) *Widget | Ищет по имени в списке созданных в программе окон, возвращает найденный указатель на структуру Widget |
Widg(sName string) *Widget | Ищет по имени в списке созданных в программе виджетов, возвращает найденный указатель на структуру Widget |
ToString(xParam ...interface{}) string | Преобразует параметры в json-строку для отправки на GuiServer |
OpenMainForm(sForm string) bool | Открывает xml форму с описанием главного окна, предварительно подготовленную с помощью HwGUI Designer |
OpenForm(sForm string) bool | Открывает xml форму с описанием диалогового окна, предварительно подготовленную с помощью HwGUI Designer |
OpenReport(sForm string) bool | Открывает xml форму с описанием отчета, предварительно подготовленную с помощью HwGUI Designer |
CreateFont(pFont *Font) *Font | Создает шрифт на основе структуры Font |
CreateStyle(pStyle *Style) *Style | Создает стиль на основе структуры Style |
CreateHighliter(sName string, sCommands string, sFuncs string, sSingleLineComm string, sMultiLineComm string, bCase bool) *Highlight |
Создает Highlight структуру для подсветки синтаксиса в виджете редактирования cedit. |
SetHighliter(pEdit *Widget, p *Highlight) | Устанавливает структуру Highlight в виджет типа cedit. |
SetHiliOpt(pEdit *Widget, iGroup int, pFont *Font, tColor int32, bColor int32) |
Устанавливает опции подсветки синтаксиса для виджета типа cedit. |
InitPrinter(pPrinter *Printer, sFunc string, fu func([]string) string, sMark string) *Printer |
Инициализирует принтер - подробнее см. здесь. |
EvalProc(s string) | Передает на GuiServer для выполнения программный код на языке Harbour |
EvalFunc(s string) []byte | Передает на GuiServer для выполнения программный код на языке Harbour, возвращает результат |
GetValues(pWnd *Widget, aNames []string) []string | Возвращает массив строк - значений виджетов окна pWnd, перечисленных по идентификаторам в массиве aNames. |
GetVersion(i int) string | Возвращает версию GuiServer. Если i==0 - номер версии, i==1 - полную строку с номером версии, i==2 - версию GuiServer, HwGUI и Harbour |
MsgInfo(sMessage string, sTitle string, fu func([]string) string, sFunc string, sName string) |
Создает стандартный Info диалог. sMessage - текст сообщения, sTitle - заголовок окна; fu, sFunc - callback функция и ее идентификатор, эта функция вызывается после закрытия диалога; sName - эта строка будет первой в массиве, передаваемом callback функции при ее вызове. Подробнее см. выше. |
MsgStop(sMessage string, sTitle string, fu func([]string) string, sFunc string, sName string) |
Создает стандартный Stop диалог. Параметры те же, что и в MsgInfo. |
MsgYesNo(sMessage string, sTitle string, fu func([]string) string, sFunc string, sName string) |
Создает стандартный YesNo диалог. Параметры те же, что и в MsgInfo. Возвращает true или false через callback функцию. |
MsgGet(sMessage string, sTitle string, iStyle int32, fu func([]string) string, sFunc string, sName string) |
Создает диалог для ввода строки. Параметры те же, что и в MsgInfo, iStyle - стиль виджета Edit. Возвращает введенную строку через callback функцию. |
Choice(arr []string, sTitle string, fu func([]string) string, sFunc string, sName string) |
Создает диалог для выбора из массива строк arr. Остальные параметры те же, что и в MsgInfo. Возвращает номер выбранной строки через callback функцию. |
SelectFile(sPath string, fu func([]string) string, sFunc string, sName string) |
Вызывает стандартный диалог выбора файла, sPath - начальный путь. Остальные параметры те же, что и в MsgInfo. Возвращает имя файла через callback функцию. |
SelectFolder(fu func([]string) string, sFunc string, sName string) |
Вызывает стандартный диалог выбора каталога. Параметры те же, что и в MsgInfo. Возвращает имя каталога через callback функцию. |
SelectColor(iColor int32, fu func([]string) string, sFunc string, sName string) |
Вызывает стандартный диалог выбора цвета, iColor - начальный цвет. Остальные параметры те же, что и в MsgInfo. Возвращает код цвета через callback функцию. |
SelectFont(fu func([]string) string, sFunc string, sName string) |
Вызывает стандартный диалог выбора шрифта. Параметры те же, что и в MsgInfo. Возвращает параметры выбранного шрифта через callback функцию. |
InsertNode(pTree *Widget, sNodeName string, sNodeNew string, sTitle string, sNodeNext string, aImages []string, fu func([]string) string, sCode string) |
Добавляет новый элемент в дерево - pTree. |
SelectNode(pTree *Widget, sNodeName string) | Делает текущим узел дерева, указывая его по имени sNodeName, заданному в InsertNode(). |
PBarStep(pPBar *Widget) | Передает прогресс-бару команду сделать следующий шаг. |
PBarSet(pPBar *Widget, iPos int) { | Устанавливает прогресс-бар в положение iPos. |
InitTray(sIcon string, sMenuName string, sTooltip string) |
Устанавливает опции размещения иконки главного окна в tray (только для Windows). |
ModifyTrayIcon(sIcon string) | Изменяет иконку в tray. |
RadioEnd(p *Widget, iSel int) | Завершает объявление радиогруппы. |
TabPage(pTab *Widget, sCaption string) | Начинает объявление страницы виджета tab |
TabPageEnd(pTab *Widget) | Завершает объявление страницы виджета tab |
BrwSetArray(pBrowse *Widget, arr *[][]string) | Устанавливает массив для отображения в виджет browse |
BrwGetArray(pBrowse*Widget) [][]string | Получает отредактированный массив от обратно от виджета browse. |
BrwSetColumn(pBrowse *Widget, ic int, sHead string, iAlignHead int, iAlignData int, bEditable bool, iLength int) | Устанавливает опции колонки номер ic виджета browse: iAlignHead - выравнивание заголовка, iAlignData - выравнивание ячейки, bEditable - возможность редактирования, iLength - длина. |
BrwSetColumnEx(pBrowse *Widget, ic int, sParam string, xParam interface{}) |
Устанавливает дополнительные опции колонки номер ic виджета browse; sParam - название опции, xParam - значение. |
BrwDelColumn(pBrowse *Widget, ic int) | Удаляет колонку номер ic виджета browse |
SetVar(sVarName string, sValue string) | Создает на GuiServer Public переменную sVarName (если ее нет) и устанавливает ее значение sValue |
GetVar(sVarName string) string | Возвращает с GuiServer значение переменной sVarName |
SetImagePath(sValue string) | Передает на GuiServer путь по умолчанию для файлов изображений |
SetPath(sValue string) | Передает на GuiServer путь по умолчанию для чтения/записи файлов |
SetDateFormat(sValue string) | Передает на GuiServer желаемый формат вывода даты |
Menu(sTitle string) | Начинает объявление меню или субменю |
MenuContext(sName string) | Начинает объявление контекстного меню |
ShowMenuContext(sName string, pWnd *Widget) | Показывает контекстное меню, sName - идентификатор меню, pWnd - окно, к которому оно относится. |
EndMenu() | Завершает объявление меню или субменю |
AddMenuItem(sName string, id int, fu func([]string) string, sCode string, params ...string) |
Добавляет пункт меню, sName - имя, id - числовой идентификатор, остальные параметры те же, что и в MsgInfo. |
AddCheckMenuItem(sName string, id int,fu func([]string) string, sCode string, params ...string) |
Добавляет пункт меню, который можно помечать. Параметры - те же, что в AddMenuItem(). |
AddMenuSeparator() | Добавляет в меню линию-разделитель |
MenuItemEnable(sWndName string, sMenuName string, iItem int, bValue bool) |
Меняет доступность элемента меню - в зависимости от значения bValue. Здесь sWndName - идентификатор окна, если это главное меню или меню диалога, sMenuName - идентификатор меню, если это контекстное меню, iItem - id пункта меню. |
MenuItemCheck(sWndName string, sMenuName string, iItem int, bValue bool) |
Отмечает или снимает отметку с пункта меню - в зависимости от значения bValue. Параметры те же, что и в MenuItemEnable. |
Первое, что надо сделать при при создании печатного документа - это создать структуру Printer, которая имеет следующий вид:
type Printer struct { Name string // Идентификатор принтера SPrinter string // Имя принтера BPreview bool // True, если нужно превью IFormType int // Тип бумаги, см. в Приложении, по умолчанию - DMPAPER_A4 BLandscape bool // True, если нужна альбомная ориентация }
Здесь Name - идентификатор принтера, поле, аналогичное таким же идентификаторам в Widget, Font, Style. SPrinter - имя принтера в системе. Если SPrinter не указан, будет использоваться принтер по умолчанию; если его значение - "...", то появится стандартное диалоговое окно для выбора принтера.
Затем инициализируем принтер с помощью функции InitPrinter(), которой передаем созданную структуру.
InitPrinter(pPrinter *Printer, sFunc string, fu func([]string) string, sMark string) *Printer
Параметры sFunc, fu, sMark (те же, что в функциях, вызывающих стандартные диалоги), используются в тех случаях, когда поле Sprinter структуры Printer равно "...", т.е., требуется стандартный диалог выбора принтера. Напомню, fu - функция, которая должна быть вызвана по завершении диалога, sFunc - ее идентификатор, sMark - первый элемент массива строк, который будет передан этой функции.
После инициализации принтера можно приступать к печати. Ниже - список методов структуры Printer, которые при этом используются:
AddFont(pFont *Font) *Font | Добавляет шрифт |
SetFont(pFont *Font) | Устанавливает текущий шрифт для печати |
Say(iTop, iLeft, iRight, iBottom int32, sText string, iOpt int32) | Печатает текст sText в прямоугольной области с координатами iTop, iLeft, iRight, iBottom. iOpt - тип выравнивания ( DT_LEFT, DT_RIGHT, DT_CENTER ) |
Line(iTop, iLeft, iRight, iBottom int32) | Рисует линию в заданных координатах |
Box(iTop, iLeft, iRight, iBottom int32) | Рисует прямоугольник в заданных координатах |
StartPage() | Начинает новую страницу печати, этот вызов обязателен. |
EndPage() | Завершает печать страницы, этот вызов обязателен. |
End() | Завершает печать, освобождает принтер. |
Все координаты указаны в миллиметрах.
Вот пример печати одной простой страницы:
func fprint(p []string) string { // Функция первоначально вызывается из главного меню if p[0] == "menu" { egui.InitPrinter(&egui.Printer{SPrinter: "...", BPreview: true}, "fprint", fprint, "mm1") } else { // Повторно она же вызывается после выбора принтера из стандартного диалога pPrinter := egui.PLastPrinter pFont := pPrinter.AddFont(&egui.Font{Family: "Times New Roman", Height: 10}) pPrinter.StartPage() pPrinter.SetFont(pFont) pPrinter.Box(5, 5, 200, 282) pPrinter.Say(50, 10, 165, 26, "Printing first sample !", egui.DT_CENTER) pPrinter.Line(45, 30, 170, 30) pPrinter.Line(45, 5, 45, 30) pPrinter.Line(170, 5, 170, 30) pPrinter.Say(50, 120, 150, 132, "----------", egui.DT_CENTER) pPrinter.Box(50, 134, 160, 146) pPrinter.Say(50, 135, 160, 146, "End Of Report", egui.DT_CENTER) pPrinter.EndPage() pPrinter.End() } return "" }
Если что-то осталось неясным, какой-то информации не хватает, смотрите примеры в external/testdata, раздел по External в туториале etutor. Еще один источник информации - группа Guiserver на GoogleGroups.
В некоторых случаях вам придется обратиться к документации Harbour и HwGUI. Так, чтобы установить в качестве callback функции Harbour код, выполняемый на GuiServer, или выполнить код на GuiServer с помошью EvalProc(), EvalFunc(), желательно чуть-чуть знать и понимать язык Harbour и HwGUI. Точно так же, чтобы непосредственно установить какой-либо атрибут виджета с помощью SetParam() или BrwSetColumnEx(), надо знать , что это за атрибуты (подсказка: это переменные классов HwGUI).
Фактически, Harbour - встроенный скриптовый язык вашего приложения. Наличие такого инструмента может оказаться очень полезным.
Список возможных значений поля Anchor структуры Widget:
A_TOPLEFT | = -1 // Anchors control to the top and left borders of the container and does not change the distance between the top and left borders. (Default) |
A_TOPABS | = 1 // Anchors control to top border of container and does not change the distance between the top border. |
A_LEFTABS | = 2 // Anchors control to left border of container and does not change the distance between the left border. |
A_BOTTOMABS | = 4 // Anchors control to bottom border of container and does not change the distance between the bottom border. |
A_RIGHTABS | = 8 // Anchors control to right border of container and does not change the distance between the right border. |
A_TOPREL | = 16 // Anchors control to top border of container and maintains relative distance between the top border. |
A_LEFTREL | = 32 // Anchors control to left border of container and maintains relative distance between the left border. |
A_BOTTOMREL | = 64 // Anchors control to bottom border of container and maintains relative distance between the bottom border. |
A_RIGHTREL | = 128 // Anchors control to right border of container and maintains relative distance between the right border. |
A_HORFIX | = 256 // Anchors center of control relative to left and right borders but remains fixed in size. |
A_VERTFIX | = 512 // Anchors center of control relative to top and bottom borders but remains fixed in size. |
Эти значения можно комбинировать. Например, egui.A_LEFTABS+egui.A_RIGHTABS - такой виджет, привязанный к левому и правому краям, будет растягиваться в ширину при растягивании окна.
DT_LEFT | Выравнивание влево |
DT_CENTER | Выравнивание вправо |
DT_RIGHT | Выравнивание по центру |
ES_PASSWORD | Ввод пароля (для Edit) |
ES_MULTILINE | Многострочный Edit |
ES_READONLY | Edit - только для чтения |
WS_HSCROLL | Горизонтальный скролл |
WS_VSCROLL | Вертикальный скролл |
WND_NOTITLE | |
WND_NOSYSMENU | |
WND_NOSIZEBOX |
DMPAPER_A3 | A3 297 x 420 mm |
DMPAPER_A4 | A4 210 x 297 mm |
DMPAPER_A5 | A5 148 x 210 mm |
DMPAPER_A6 | A6 105 x 148 mm |
1 | вертикальный сверху вниз |
2 | вертикальный снизу вверх |
3 | горизонтальный слева направо |
4 | горизонтальный справа налево |
5 | диагональный справа вверх |
6 | диагональный слева вниз |
7 | диагональный справа вниз |
8 | диагональный слева вверх |
9 | радиальный градиент |
Здесь приведен список идентификаторов событий, поддерживаемых к моменту написания этого руководства - тех идентификаторов, которые можно указать в SetCallBackProc() и SetCallBackFunc().
oninit | |
ondestroy | |
onclick | |
onsize | |
onpaint | |
onrclick | |
ondblclick | |
onenter | |
onposchanged |
Ваше имя:
Адрес электронной почты:
(не предназначено к показу)
  |