Geniepro писал(а):
Я так понимаю, что никаких демо-версий не доступно? Можно хоть где-то посмотреть описание библиотеки, её возможностей, архитектуры там, скриншоты, наконец? Есть ли какие демо-примеры использования этой библиотеки?
Документация по библиотеке выложена здесь:
http://oberoncore.ru/library/startПравда, там довольно старый документ, но архитектурно изменений почти не было. Я попрошу Штефана сгенерировать свежую версию.
Фирменный сайт пока что нетрудоспособен.
Демо-версий библиотеки не предусмотрено. Если есть идеи, как это можно организовать, готов выслушать.
Скриншот моей первой полезной людям программы на Amadeus:
Вложение:
NoLimit.PNG [ 11.05 КБ | Просмотров: 11969 ]
Программа предназначена для снятия демо-ограничения с прибора (для этого надо ввести пароль, установленный разработчиками). Далее файл ресурсов (аналог Delphi .dfm) NoLimit.tx3 - может поставляться как в текстовом виде, так и в бинарном - с расширением .ap3:
Код:
OBJ Prj "NoLimit"
REQUIRES NONE
OBJ Cmd BASEID 1 ClearLimit 106
ENDOBJ
OBJ DataDict
MEMBERS
OBJ Str "result" LEN 1024 MAXLINE 4 ENDOBJ
OBJ Str "password" LEN 9 ENDOBJ
OBJ NumRange "portNum" 1 ; 100 ENDOBJ
OBJ Num "portNum" SHORT LEN 0 NOZERO RANGE "portNum" ENDOBJ
ENDGRP
ENDOBJ
OBJ Group "NoLimitApp"
MEMBERS
OBJ Font "copyright" "Tahoma;H=12;A=2;#=204;P=f;Z;X" ENDOBJ
OBJ Win "MAIN" ACTIVE ICONIZE SYSMENU THINFRM BRUSH "BtnFace" POS 19 , 14 405 , 256 CLIENT 399 , 231 SCROLL 1 , 1
TITLE "Снять ограничение"
PARTS
OBJ Field "Номер COM-порта:" ACCESS POS 30 , 6 390 , 28 VALUE portNum ALIGNOPPOSITE OFFSET 107 ENDOBJ
OBJ Field "Пароль:" ACCESS POS 88 , 33 390 , 55 VALUE password OFFSET 49 ENDOBJ
OBJ Button "Снять ограничение (Enter)" ID ClearLimit ACCESS DEF POS 137 , 60 390 , 87 ENDOBJ
OBJ Field "Результат:" ACCESS POS 78 , 93 390 , 147 VALUE result OFFSET 59 BG "BtnFace" ENDOBJ
OBJ Button "Выход (Esc)" ID Exit ACCESS POS 137 , 153 390 , 180 ENDOBJ
OBJ Text ACCESS POS 9 , 188 355 , 224 FONT "copyright" FG "Black"
TEXT
'(c) Александр Ильин, 2007 для ООО "НПП Томьаналит".'
"Программа написана на языке Oberon-2 с использованием компилятора"
"XDS (c) Excelsior и библиотеки Amadeus-3 (с) Stefan Metzeler."
ENDOBJ
END
ENDOBJ
ENDGRP
ENDOBJ
ENDOBJ
А вот так выглядит главный модуль программы:
Код:
<*+main*>
MODULE NoLimit;
(* ------------------------------------------------------------------------
* (C) 2007 by Alexander Iljin
* ------------------------------------------------------------------------ *)
IMPORT
Windows,
WinMgr, WinEvent, Startup, Events, Commands, Dialogs, Persist, Actions, Help,
Keys, Reports, PStore, SrcSelect, App := NoLimitApp, Timers, Values,
Fields, TA4, Endup, Resource, Str, Convert, CommData, TA4Device, NumVal;
CONST
Settings = 'Settings';
PortNum = 'PortNum';
TimeOut = 3000; (** if there is no reply in this time [ms], the error is reported *)
TYPE
Project* = POINTER TO ProjectDesc;
ProjectDesc* = RECORD (Startup.ProjectDesc)
timer: Timers.Timer;
transactionStart: Windows.DWORD;
resultField: Fields.Field;
device: TA4.Device;
expectingReply: BOOLEAN;
END;
VAR
project*: Project;
PROCEDURE AppendResult (str: ARRAY OF CHAR);
BEGIN
Str.Append(App.result, str);
IF project.resultField # NIL THEN
project.resultField.Refresh(NIL, 0);
END;
END AppendResult;
PROCEDURE ^ (p: Project) ClearLimit ();
PROCEDURE TimerTick (t: Timers.Timer);
VAR str: Str.PStr;
BEGIN
project.device.Update;
IF project.expectingReply THEN
CommData.DataToStr(project.device.data, str);
IF str = NIL THEN
IF Windows.GetTickCount() - project.transactionStart > TimeOut THEN
project.expectingReply := FALSE;
AppendResult('Прибор не отвечает');
END;
ELSIF str^ = TA4Device.LimitRemoved THEN
project.expectingReply := FALSE;
AppendResult('Ограничение снято');
ELSIF str^ = TA4Device.LimitSet THEN
(* oops - we have set the limit instead of clearing it *)
project.expectingReply := FALSE;
AppendResult('Ограничение установлено');
(* call ClearLimit again to clear *)
project.ClearLimit;
ELSIF str^ = TA4Device.BadIdentifier THEN
project.expectingReply := FALSE;
AppendResult('Неправильный пароль');
ELSE
AppendResult('Неизвестный ответ прибора: ');
AppendResult(str^);
END;
END;
END TimerTick;
PROCEDURE StrToPassword (VAR str: ARRAY OF CHAR): TA4Device.Password;
VAR
res: TA4Device.Password;
i: INTEGER;
BEGIN
i := 0;
WHILE i < LEN(res) DO
res[i] := '0';
INC(i);
END;
i := 0;
WHILE (i < LEN(res)) & (str[i] # 0X) DO
res[i] := str[i];
INC(i);
END;
RETURN res;
END StrToPassword;
PROCEDURE (p: Project) ClearLimit ();
VAR
s: Str.MediumStr;
f: Fields.Field;
BEGIN
IF p.expectingReply THEN
AppendResult('Ожидается ответ от прибора... ');
RETURN
END;
App.result := '';
AppendResult(''); (* to update the value on screen *)
IF p.device.Connect(App.portNum) THEN
IF p.device.ClearLimit(StrToPassword(App.password)) THEN
project.expectingReply := TRUE;
project.transactionStart := Windows.GetTickCount();
END;
ELSE
AppendResult('Не удалось открыть порт COM');
Convert.IntToStr(App.portNum, 0, FALSE, s);
AppendResult(s);
END;
END ClearLimit;
PROCEDURE (p: Project) Handler* (w: WinMgr.Window; VAR ev: Events.Event);
(** Method handles all the top-level events that weren't handled elsewhere *)
BEGIN
IF (ev.tp = Events.Key) & (ev.action = Events.Press) & (ev.key = Keys.Esc)
THEN
ev.tp := Events.Command;
ev.code := Commands.Exit;
END;
IF (ev.tp = Events.Close) & (w = WinMgr.mainW) THEN
WinMgr.mainW.Destroy;
ELSIF (ev.tp = Events.Command) & ~ev.done THEN
ev.done := TRUE;
CASE ev.code OF
| App.ClearLimitCmd:
p.ClearLimit;
| Commands.Exit:
WinMgr.mainW.Destroy;
ELSE
ev.done := FALSE;
END; (* case ev.code *)
END; (* if ev.tp *)
Timers.Handler(ev);
Actions.Handler(w, ev);
Help.Handler(w, ev);
END Handler;
PROCEDURE LoadSettings ();
VAR
s: Convert.NumberStr;
i: INTEGER;
BEGIN
IF (Resource.Get(Settings, PortNum, s) > 0) & Convert.StrToInt(s, i)
& NumVal.InRange(App.portNumRange, i)
THEN
App.portNum := SHORT(i);
ELSE
App.portNum := 1;
END;
END LoadSettings;
PROCEDURE SaveSettings ();
VAR
b: BOOLEAN;
s: Convert.NumberStr;
BEGIN
Convert.IntToStr(App.portNum, 0, FALSE, s);
b := Resource.Set(Settings, PortNum, s);
END SaveSettings;
PROCEDURE (p: Project) InitInstance* (): BOOLEAN;
VAR
b: BOOLEAN;
f: Fields.Field;
BEGIN
IF ~(PStore.LoadProject(project.name^, App.thisProject, App.Init))
OR ~p.InitInstance^() OR ~Startup.CallInitProcs(Startup.OnInitInstance)
THEN
RETURN FALSE
END;
b := WinMgr.mainW.Create();
WinMgr.mainW.Show(WinMgr.TopPos);
p.device := TA4.New();
p.timer := Timers.New(WinMgr.mainW.hWnd);
p.timer.handler := TimerTick;
p.timer.SetInterval(50);
p.timer.Start;
p.expectingReply := FALSE;
LoadSettings;
IF Fields.FindByData(WinMgr.mainW, App.portNum, Fields.IgnoreIndex, f) THEN
f.Refresh(NIL, 0);
END;
IF Fields.FindByData(WinMgr.mainW, App.result, Fields.IgnoreIndex, f) THEN
p.resultField := f;
END;
Endup.Install(SaveSettings);
RETURN TRUE
END InitInstance;
BEGIN
NEW(project);
project.Init;
project.SetName('NoLimit');
Startup.WinStart(project);
END NoLimit.