Форум » Clipper » Вопрос по сборке проекта » Ответить

Вопрос по сборке проекта

yukirin: использую Clipper 5.2e portable выкачанный по адресу http://softclipper.narod.ru/download.html. При сборке проекта rtlink предлагает указать путь до библиотеки CE50.LIB. Подскажите пожалуйста где найти данный файлик... или полноценную папку со всеми библиотеками. Опыт работы с clipper отсутсвует а экзешник собрать очень хочется. Please help...

Ответов - 67, стр: 1 2 3 4 All

AlexMyr: yukirin пишет: Подскажите пожалуйста где найти данный файлик... Ищите в папке CLIPPER\LIB.

yukirin: Хороший ответ... Изменю вопрос - может ли кто-нибудь поделиться папкой LIB с уже существующей там библ. CE50.LIB, т.к. в том варианте Clipper 5.2e который я скачал данная библиотека отсутствует.

yukirin: Кстати ссылку я неправильную дал - http://softclipper.net/soft-skachat/clipper-5-2e-portable.html - вот по этой ссылке выкачивал. Там было написано "самая стабильная версия со всеми обновлениями и дополнительными библиотеками". А оказалось что не со всеми...


Dima: yukirin пишет: CE50.LIB Не припомню такой библиотеки yukirin пишет: Там было написано "самая стабильная версия со всеми обновлениями и дополнительными библиотеками" Надо понимать что там библиотеки от Clipper + Clipper Tool и среди них не было ни когда CE50.LIB

yukirin: Нужна помощь в сборке проекта. У меня имеется голый исходник размером в 28700 строк который мне достался от одного человека со словами - что это единственный существующий текст программы - другого нет. У меня получить работоспособный экзешник не получается - есть два-три десятка функций на которые блинкер ругается как на не существующие внешние ссылки. Что необходимо подключить( библиотеки, include) я не знаю и подобрать не получается. Вполне возможно что исходник подпорченный ( причем специально). Опыт написания на клиппер, как я писал выше, отсутствует вообще. Пишу на с++... В общем прошу помощи в получении хотя бы нормально запускающегося экзешника))). Для откликнувшихся моя почта - yukirin@yandex.ru или пишите вашу - отправлю.

Pasha: Дайте список нереализованных ссылок. Возможно, они из какой-нибудь распространенной библиотеки, которую надо будет прилинковать.

yukirin: Обновился до версии 5.3b. Подключил в скрипте блинкера файл ctus и изменил библиотеку с ctp на ct - количество ссылок сократилось: BLINKER : 1115 : TORG_11.OBJ(TORG_11) : 'GOTOBOTTOM' : unresolved external BLINKER : 1115 : TORG_12.OBJ(TORG_12) : 'ERRORMESSA' : unresolved external BLINKER : 1115 : TORG_12.OBJ(TORG_12) : 'POSTACTIVE' : unresolved external BLINKER : 1115 : TORG_21.OBJ(TORG_21) : '_NEWCLASS' : unresolved external BLINKER : 1115 : TORG_21.OBJ(TORG_21) : '_ADDMETHOD' : unresolved external BLINKER : 1115 : TORG_22.OBJ(TORG_22) : 'GETREADVAR' : unresolved external BLINKER : 1115 : TORG_31.OBJ(TORG_31) : 'SETCLASS' : unresolved external Вот мой скрипт blinker'а: BLINKER EXECUTABLE CLIPPER F:250;SWAPK:8192;SWAPPATH:C:\TMP BLINKER EXECUTABLE NODELETE BLINKER PROCEDURE DEPTH 100 #BLINKER EXECUTABLE EXTENDED BLINKER INCREMENTAL OFF #BLINKER EXE COMPERSS 1 NOBEL STACK 10240 FILE TORG_11 FILE TORG_12 FILE TORG_21 FILE TORG_22 FILE TORG_31 FILE TORG_32 FILE CTUS LIBRARY CPMI LIBRARY NANFOR LIBRARY CLIPPER LIBRARY TERMINAL LIBRARY EXTEND LIBRARY CT попробовал запустить то что получилось)))) - получил ошибку - RDDREGISTE(0) Internal error 9002 Читал про возможность декомпиляции. Вопрос какова вероятность получения рабочих исходников для возможности дальнейшего сопровождения программы.

Pasha: Если исходная программа собрана rtlink'ом, то ее декомпилировать можно, если блинкером - нет. Функций осталось совсем немного, и достаточно их найти или сделать им замену. PostAvtive, GetReadVar - эти функции есть в clipper 5.3, так что лучше собрать проект этой версией компилятора _NewClass, __AddMethod, SetClass - это явно из какой-то библиотеки для ООП Это не classy, но этих библиотек не так много, надо пересмотреть GOTOBOTTOM - покажите, в каком контексте идет вызов этой функции, чтобы понять что она делает ErrorMessage - можно просто добавить заглушку: func ErrorMesssage return ""

yukirin: так ведь и обновился до версии 5.3б GETREADVAR и POSTACTIVE также unresolved external по поводу GOTOBOTTOM: function TBROWSEIND(Arg1, Arg2, Arg3, Arg4, Arg5) local Local1 Local1:= tbrowsenew(Arg1, Arg2, Arg3, Arg4) settbrowse(Local1, Arg5) return Local1 ******************************** procedure SETTBROWSE(Arg1, Arg2) Arg1:gotopbloc({|_1| (_1:= Set(_SET_SOFTSEEK, .T.), dbSeek(Arg2), Set(_SET_SOFTSEEK, _1))}) Arg1:gobottomb({|| gotobottom(Arg2)}) //функция на которую ругается блинкер Arg1:skipblock({|_1| movepointe(_1, Arg2)}) ******************************** пример вызова TBROWSEIND в которой исполбзуется - gotobottom wbox() Local1:= tbrowseind(0, 0, MaxRow() - 1, MaxCol(),Str(doch->iddoc)) //------------------------------------------------------------------------------------------------// Где взять эти ООП библиотеки? Этот класс используется при печати.

Pasha: gotobottom - это судя по всему seek last т.е. можно добавить эту функцию: func gotobottom(Arg) Local lSoft := Set(_SET_SOFTSEEK, .T.) dbSeek(Arg,, .t.) Set(_SET_SOFTSEEK, lSoft) return nil GETREADVAR и POSTACTIVE должны быть в lib\clipper.lib, размер 694791 от 20.05.1997 Насчет ООП - есть ли в проекте какие-нибудь файлы *.ch, связанные с библиотекой ООП ? Я именно такую не вспомню, пересмотрел какие у меня есть ООП-библиотеки

Pasha: Ага, GETREADVAR и POSTACTIVE это static-функции, значит используется какая-то альтернативная get-система Т.е. исходные тексты не все. Можно попробовать взять модуль source\sys\getsys.prg, найти строки Static function GETREADVAR(..) и Static function PostActive(..) и заменить их на function GETREADVAR(..) и function PostActive(..) Кстати, сырцы похоже получены именно декомпилятором

yukirin: проблема не в исходнике потому как я нашел эти функции в тексте. Проблема видимо в том что я не правильно поделил сам текст программы на куски . Дело в том что переданный мне исходник шел одним файлом и клипер при компиляции выдавал - to many labels и не создавал объектный файл. Мне посоветовали просто раздробить программу на куски что я не задумываясь и сделал. Как правильно разделить текст на куски? Можно ли сделать так что бы клиппер при компиляции с ключем /w все предупреждения писал в файл, а то их довольно много и они быстро пробегают по экрану и что там было понять невозможно. кстати GETREADVAR и POSTACTIVE и др.( кроме ООП ф-ций ) больше не unresolved external. На класс возложена печать, т.е. по идее программа должна у меня запустится без печати - но при запуске получаю - RDDREGISTE(0) Internal error 9002

alkresin: _NEWCLASS, _ADDMETHOD, SETCLASS обнаружились в Fivewin.

alkresin: yukirin пишет: Можно ли сделать так что бы клиппер при компиляции с ключем /w все предупреждения писал в файл, а то их довольно много и они быстро пробегают по экрану и что там было понять невозможно. clipper.exe my.prg /w >my.log

Pasha: yukirin пишет: Как правильно разделить текст на куски? Поскольку восстановить исходную разбивку не получится, то прийдется разбивать хорошо известным методом проб и ошибок, соблюдая некоторые правила Например, такое: static-функция должна быть определена в то модуле, откуда есть ее вызов. Надо либо перенести функцию в тот модуль, либо убрать static На класс возложена печать, т.е. по идее программа должна у меня запустится без печати - но при запуске получаю - RDDREGISTE(0) Internal error 9002 Попробуйте в скрипт сборки добавить: library dbfcdx, dbfntx, _dbfcdx

Pasha: alkresin пишет: _NEWCLASS, _ADDMETHOD, SETCLASS обнаружились в Fivewin. Символы подчеркивания вроде бы в именах функций не так расположены. Может другая библиотека ?

alkresin: Pasha пишет: Символы подчеркивания вроде бы в именах функций не так расположены. Может другая библиотека ? В моей копии objects.lib - именно так.

yukirin: вобщем линкуется сейчас без предупреждение об unresolved external подключил - objects.lib. но толку от этого мало.... RDDREGISTE(0) Internal error 9002 и все тут. DBFNTX.LIB тоже подключил. если запускать компиляцию с ключем /w - то получаем несколько тысяч предпреждений прмерно одного содержания: Warning C1003 Ambiguous reference: 'GETLIST' Warning C1003 Ambiguous reference: 'GETLIST' Warning C1004 Ambiguous reference, assuming memvar: 'GETLIST' вместо GETLIST могут быть другие переменные но с GETLIST подавляющее большинство.... пока тупик. нашел процедуру ******************************** init procedure DBFNTXINI rddregiste("DBFNTX", 1) return ******************************** мож в ней что не так вообще в тексте программы довольно много функций и процедур выдернутых из текстов представленных на страничке http://www.mythologics.com/c53/

alkresin: Обычно в клипперовских программах rddregister() напрямую для dbfntx не вызывается, это происходит автоматически при инициализации приложения. Поэтому смело выкидывайте эту процедуру.

yukirin: Нашел вызовы ф-ции rddregiste два раза - один раз с параметром DBF другой DBFNTX. Закомментировал. Получил окно при запуске - unrecoverable error 650: Processor stack fault. Про что в инете пишут Бесконечная рекурсия. Дааа. Объясните пожалуйста как пользоватся клипперовским отладчиком. Я так понял это файл CLD.EXE. Но в в версии 5.3 нет такого файла там есть CLDR.EXE - это он? Откомпилировал прогу с ключом /b, запустил CLDR c параметром MYEXE.EXE и получил бяку.. Что то про то что нет такого файла, хотя файл рядом лежит. З.Ы. насколько критичны варнинги приведенные мной в посте №8 ?

alkresin: Про отладчик ничего не скажу - я 5.3 никогда не пользовался. Попробуйте расставить в начале программы, например, вызовы Alert("какой-то текст") - эта функция выдает на экран box с текстом - для простейшей трассировки. Warning'и эти не критичны. Они означают, что данная переменная не объявлена как Memvar, это не преступление. Если какая-то переменная вообще не объявлена, может в процессе исполнения выскочить ошибка - что нет такой-то переменной, но никак не Processor stack fault.

yukirin: Закомментировал все init procedure т.к. они по названию и содержанию повторяют процедуры, например, со страницы http://www.mythologics.com/c53/_cliplib.html ( init procedure CLIPINIT ) и др. Я так понимаю что инит процедуры автоматитически прилинковываются после присоединения файла библиотки в скрипте линкера или надо как то явно указывать необходимость вызова той же CLIPINIT, т.к. у меня после комментирования всех уже и так существующих в CLIPPER.LIB инит процедур экзешник запускается и тут же завершается без каких либо сообщений, соответсвенно до alert не доходим. (((Меня начинают посещать мысли о неосуществимости моей затеи по получению рабочей программы..... Еще сегодня помучаюсь и завтра начну, наверное, пробовать декомпилировать.....

yukirin: Где можно посмотреть полный список ф-ций/процедур содержащихся в клиппер.либ версии 5.2е?

alkresin: yukirin пишет: у меня после комментирования всех уже и так существующих в CLIPPER.LIB инит процедур экзешник запускается и тут же завершается без каких либо сообщений, соответсвенно до alert не доходим. Я бы в таком случае действовал следующим образом: урезал бы программу до минимума, скомпилировал, запустил. Если работает ( если - нет, значит с моим компилятором что-то не то ), то добавляем фрагмент, проверяем - и т.д. yukirin пишет: Где можно посмотреть полный список ф-ций/процедур содержащихся в клиппер.либ версии 5.2е? В ng ( Norton Guide ) соответствующем. А если совсем полный :), то какой-нибудь утилитой, выдающей листинг .lib файла, у меня тут несколько таких - libra.exe, libview.exe, lib.exe

nick_mi: Для запуска DEBUGGER в CLIPPER 5.3 необходимо в файле .LNK для blinker'а поставить команду FI CLD.lib В программе после запуска нажать комбинацию ALT+D

yukirin: Есть прогресс выходит первоначальная заставка затем прога вываливается на первой встретившейся ф-ции dbcreate с сообщением - ДБ КРЕАТЕ ИНТЕРНАЛ ЭРРОР. Еще почемуто попытка вставить код - alert( "ku-ku" ) приводит появлению окошка с надписью типа - OMPT (4606) и программа завершается. Но и это уже прогресс буду ковырять дальше. Непонятно зачем в текст программы были вставлены куски из декампилированного clipper.lib, причем вставлены они хаотично... Засяду ка я за очистку проги от ненужного текста....хотя это и не быстрая процедура...

Pasha: Исходники как я понимаю получены декомпилятором. А декомпилятор берет весь пи-код, который содержится в exe. Это и пользовательский пи-код, и пи-код функций клиппера, реализованных на уровне prg и содержащихся в стандартных библиотеках Декомпилятору неизвестно, из какого модуля получен пи-код, вот он и декомпилирует все, что может. Поэтому конечно стандартные функции лучше удалить, все равно они будут прилинкованы из библиотек. Скажем, можно взять модуль source\sys\getsys.prg и смело удалять из текста все функции, в нем присутствующие Правда, там есть еще static-переменные, с ними не так просто А по поводу предупреждений: перед первой функцией можно добавить строку: memvar GetList и предупреждения по этой переменной исчезнут Что до остальных предупреждений, то они могут быть и безобидными, а могут и опасными, в зависимости от того, в каком стиле написана программа. Могут быть неприятности из-за декомпиляции при разбивке текста на несколько модулей Скажем, если функция использует static-переменную, то эта переменная должна остаться в том же модуле, что и сама функция.

nick_mi: Я просто как-то пропустил, для того чтобы отладчик запускался с произвольного места необходимо вставить вызов функции ALTD()

Andrey: yukirin пишет: Нужна помощь в сборке проекта. У меня имеется голый исходник размером в 28700 строк который мне достался от одного человека со словами - что это единственный существующий текст программы - другого нет. У меня получить работоспособный экзешник не получается Давай исходник, я тебе его на хХарбор переведу и не будешь мучиться с Клипером.

Dima: Andrey пишет: Давай исходник, я тебе его на хХарбор переведу и не будешь мучиться с Клипером. Ну тогда ждем результата

yukirin: Программа начинает оживать.... собс-но уже работает за исключением печати. Печать реализована в классе TPrinter. линкуется с библиотекой objects без предупреждений... Но при попытке печати прога вываливается с ошибкой - ERROR BASE/1004 No exported method: LOAD. Расскажите пожалуйста про варианты возникновения данной ошибки.

Pasha: В коде должно быть по первых определение класса TPrinter и его методов: что-то вроде function TPRINTER _objaddmet(StaticNNN, Nil, .T., 0, "Load", {|| Load()}) Return _objclsins(StaticNNN) методы: static function load(...) return ... и где-то создание объекта класса: вызов TPrinter():new(...) В исходном коде это было бы оформлено в виде команд, а в декомпилированном - функциями. Что-нибудь подобное есть ?

yukirin: В переданном мне исходнике (кстати данный текст полчен при помощи rescue5 - мной проверено) отсутствует текст одного метода класса TPrinter, т.к. он присутствует в объявлении класса. Вопрос - можно ли как-нибудь его вычленить из экзешника (rescue - получается отказывается его извлекать)?

Pasha: Здесь есть 2 варианта: или этот метод написан на C, и тогда его декомпилировать невозможно. Но это маловероятно. 2-й вариант - декомпилятор действительно декомпилировал не весь пи-код. Но тогда это проблема небольшая, можно декомпилировать этот exe Валькирией. Валькирия имеет лучшую репутацию, чем rescue5. Чтобы труд по обработке текста и сборке проекта не пропал даром, можно перенести в уже обработанный текст программы только один этот метод, полученный Валькирией. Саму Valkyrie думаю найти несложно.

yukirin: увы и ах.....Valkyrie тоже ниче не выдала. Есть мелкая надежда на то что используемый класс не полное творение разработчика. Поэтому ниже приведен текст фнукция где этот класс создается мож с подобным классом уже кто сталкивался.... function TPRINTER static Static26 local Local1 if (ISNIL(Static26)) Static26:= _newclass("TPrinter", Local1) _addmethod({"Text1"}, Nil, Nil, 1) _addmethod({"aOpr"}, Nil, Nil, 1) _addmethod({"aVar"}, Nil, Nil, 1) _addmethod({"nStr"}, Nil, Nil, 1) _addmethod({"nList"}, Nil, Nil, 1) _addmethod({"Auto"}, Nil, Nil, 1) _addmethod({"IsPrn"}, Nil, Nil, 1) _addmethod({"Device"}, Nil, Nil, 1) _addmethod({"ReportName"}, Nil, Nil, 1) _addmethod({"cHead"}, Nil, Nil, 1) _addmethod({"cEject"}, Nil, Nil, 1) _addmethod({"cHeadFoot"}, Nil, Nil, 1) _addmethod({"cFoot"}, Nil, Nil, 1) _addmethod({"cTitul"}, Nil, Nil, 1) _addmethod({"nHeadWidth"}, Nil, Nil, 1) _addmethod({"KolStr"}, Nil, Nil, 1) _addmethod({"Ustanovki"}, Nil, Nil, 1) _addmethod({"lContinue"}, Nil, Nil, 1) _addmethod({"cFile"}, Nil, Nil, 1) _addmethod({"cSource"}, Nil, Nil, 1) _addmethod({"lLoadError"}, Nil, Nil, 1) _addmethod({"Rulon"}, Nil, Nil, 1) _addmethod({"lTempFile"}, Nil, Nil, 1) _addmethod({"Init", {|| tprninit()}}, Nil, .T., 0) _addmethod({"Load", {|| tprnload()}}, Nil, .T., 0) _addmethod({"SetDevice", {|| tprnsetdev()}}, Nil, .F., 0) _addmethod({"Process", {|| tprnproces()}}, Nil, .F., 0) _addmethod({"PrintTitul", {|| tprntitul()}}, Nil, .F., 0) _addmethod({"PrintHead", {|| tprnhead()}}, Nil, .F., 0) _addmethod({"PrintHeadFoot", {|| tprnheadfo()}}, Nil, .F., 0) _addmethod({"PrintStr", {|| tprnstr()}}, Nil, .F., 0) _addmethod({"PrintFoot", {|| tprnfoot()}}, Nil, .F., 0) _addmethod({"PrintFormula", {|| tprnprintf()}}, Nil, .F., 0) _addmethod({"Set", {|| tprnset()}}, Nil, .F., 0) _addmethod({"Done", {|| tprndone()}}, Nil, .F., 0) _addmethod({"StrTransform", {|| tprntransf()}}, Nil, .F., 0) _addmethod({"NewPage", {|| newpage()}}, Nil, .F., 0) _addmethod({"ResetPage", {|| resetpage()}}, Nil, .F., 0) _addmethod({"AddnStr", {|| tprnaddnst()}}, Nil, .F., 0) endif return __classins(Static26) ******************************** один из методов класса static function TPRNLOAD(Arg1) local Local1:= qself(), Local2, Local3:= {}, Local4:= {}, Local5, ; Local6, Local7, Local8, Local9 Local1:lloaderro(.F.) Local1:aopr({}) Local1:avar({}) if (!file(Arg1)) alert("Отсутствует файл отчетной формы " + Arg1) Local1:lloaderro(.T.) return .F. endif Local1:nstr(1) Local1:nlist(1) Local1:isprn(.T.) Local1:ctitul("") Local1:nheadwidt(40) Local1:kolstr(getcfg("KOLSTR", Arg1, "N")) if (Local1:kolstr() == 0) Local1:kolstr(75) endif Local1:device(getcfg("DEVICE", Arg1, "C")) Local1:rulon(getcfg("RULON", Arg1, "C")) if (Upper(Local1:rulon()) = "ДА") Local1:rulon(.T.) else Local1:rulon(.F.) endif Local1:ustanovki("") Local1:ustanovki(getcfg("Ustanovki", Arg1, "C")) Local1:ceject(getcfg("EJECT", Arg1, "C")) if (Empty(Local1:ceject())) Local1:ceject(" ") endif if (Empty(Local1:ustanovki()) .AND. Type("cUstanovki") != "U") Local1:ustanovki(custanovki) elseif (Upper(Local1:ustanovki()) == "НЕТ") Local1:ustanovki("") endif Local1:lcontinue(.T.) Local2:= memoread(Arg1) Local1:cfile(SubStr(Arg1, 1, Len(Arg1) - 3) + "prn") Local1:csource(memoread(Arg1)) Local1:ctitul(beforatnum(Chr(13) + Chr(10) + "ENDTITUL", ; afteratnum("TITUL" + Chr(13) + Chr(10), Local1:csource(), 1), ; 1)) Local1:chead(beforatnum(Chr(13) + Chr(10) + "ENDPAGEHEAD", ; afteratnum("PAGEHEAD" + Chr(13) + Chr(10), Local1:csource(), ; 1), 1)) Local1:cheadfoot(beforatnum(Chr(13) + Chr(10) + "ENDPAGEFOOT", ; afteratnum("PAGEFOOT" + Chr(13) + Chr(10), Local1:csource(), ; 1), 1)) Local1:cfoot(beforatnum(Chr(13) + Chr(10) + "ENDMAINFOOT", ; afteratnum("MAINFOOT" + Chr(13) + Chr(10), Local1:csource(), ; 1), 1)) Local1:reportnam("Отчет") tokeninit(@Local2, Chr(13) + Chr(10), 2) Local5:= 0 Local9:= .F. do while (!tokenend()) Local7:= tokennext(Local2) Local6:= alltrim(Local7) Local5++ do case case Left(Local6, 1) == "#" if (!Local9) Local1:reportnam(SubStr(Local7, 2)) Local9:= .T. endif loop case Upper(Local6) = "KOLSTR" .OR. Upper(Local6) = "USTANOVKI" ; .OR. Upper(Local6) = "RULON" .OR. Upper(Local6) = ; "DEVICE" .OR. Upper(Local6) = "LIST" .OR. Upper(Local6) ; = "EJECT" loop case Upper(Local6) = "TITUL" do while (!tokenend() .AND. Upper(Local6) != "ENDTITUL") Local7:= tokennext(Local2) Local5++ Local6:= alltrim(Local7) enddo case Upper(Local6) = "PAGEHEAD" do while (!tokenend() .AND. Upper(Local6) != "ENDPAGEHEAD") Local7:= tokennext(Local2) Local5++ Local6:= alltrim(Local7) enddo case Upper(Local6) = "PAGEFOOT" do while (!tokenend() .AND. Upper(Local6) != "ENDPAGEFOOT") Local7:= tokennext(Local2) Local5++ Local6:= alltrim(Local7) enddo case Upper(Local6) = "MAINFOOT" do while (!tokenend() .AND. Upper(Local6) != "ENDMAINFOOT") Local7:= tokennext(Local2) Local5++ Local6:= alltrim(Local7) enddo case Upper(Local6) = "VAR" Local6:= alltrim(SubStr(Local6, 4)) numelem:= numtoken(Local6, "," + Chr(13) + Chr(10)) for Local8:= 1 to numelem AAdd(Local1:avar(), alltrim(token(Local6, "," + Chr(13) ; + Chr(10), Local8))) Local5++ next case Upper(Local6) = "AUTO" Local5++ Local1:auto(.T.) case SubStr(Local6, 1, 2) = "@ " Local6:= LTrim(SubStr(Local6, 2)) Local7:= alltrim(Local6) do case case Upper(Local7) = "IF" AAdd(Local1:aopr(), {"IF", alltrim(SubStr(Local7, 3)), ; Local5, 0, &("{||" + alltrim(SubStr(Local7, 3)) + ; "}")}) AAdd(Local3, Len(Local1:aopr())) case Upper(Local7) = "ELSE" if (Len(Local3) == 0) alert("Ошибка в составлении условных операторов;Строка" ; + Str(alltrim(Local5))) Local1:lloaderro(.T.) return .F. endif if (Empty(SubStr(Local7, 5))) AAdd(Local1:aopr(), {"ELSE", alltrim(SubStr(Local7, ; 5)), Local5, 0}) else AAdd(Local1:aopr(), {"ELSE", alltrim(SubStr(Local7, ; 5)), Local5, 0, &("{||" + alltrim(SubStr(Local7, ; 5)) + "}")}) endif Local1:aopr()[ATail(Local3)][4]:= Len(Local1:aopr()) Local3[Len(Local3)]:= Len(Local1:aopr()) case Upper(Local7) = "ENDIF" if (Len(Local3) == 0) alert("Ошибка в составлении условных операторов;Строка " ; + alltrim(Str(Local5))) Local1:lloaderro(.T.) return .F. endif AAdd(Local1:aopr(), {"ENDIF", "", Local5, 0}) Local1:aopr()[ATail(Local3)][4]:= Len(Local1:aopr()) asize(Local3, Len(Local3) - 1) case Upper(Local7) = "WHILE" AAdd(Local1:aopr(), {"WHILE", alltrim(SubStr(Local7, ; 6)), Local5, 0, &("{||" + alltrim(SubStr(Local7, 6)) ; + "}")}) AAdd(Local4, Len(Local1:aopr())) case Upper(Local7) = "ENDWHILE" if (Len(Local4) == 0) Local1:lloaderro(.T.) alert("Ошибка в составлении условных операторов;Строка " ; + alltrim(Str(Local5))) return .F. endif AAdd(Local1:aopr(), {"ENDWHILE", "", Local5, ; ATail(Local4)}) Local1:aopr()[ATail(Local4)][4]:= Len(Local1:aopr()) asize(Local4, Len(Local4) - 1) case "{|" $ Upper(Local7) .OR. "&" $ Upper(Local7) AAdd(Local1:aopr(), {"OP", Local7, Local5, 0, "{||" + ; Local7 + "}"}) otherwise AAdd(Local1:aopr(), {"OP", Local7, Local5, 0, &("{||" + ; Local7 + "}")}) endcase case SubStr(Local6, 1, 1) != "@" AAdd(Local1:aopr(), {"STR", Local7, Local5, 0}) endcase enddo for Local8:= 1 to Len(Local1:avar()) Local6:= Local1:avar()[Local8] if (Type("M->" + Local6) = "U") public &Local6 endif next return ******************************** процедура через которую осуществляется печать форм: procedure PRINTFORM(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) local Local1, Local2 if (demoflag) demo() else showmessag("Формирую отчет.") Arg3:= iif(Arg3 = Nil, .F., Arg3) Arg4:= iif(Arg4 = Nil, .F., Arg4) Arg5:= iif(Arg5 = Nil, .F., Arg5) Arg6:= iif(Arg6 = Nil, 0, Arg6) if (file(dallvod + Arg1)) Local1:= tprinter():load(dallvod + Arg1) else Local1:= tprinter():load(dvod + Arg1) endif if (Local1:lloaderror()) showmessag() else if (Arg2 != Nil) Local1:device(Arg2) endif Arg2:= iif(!Empty(ctempdir), ctempdir + "\", "") + ; Local1:device() if (Local1:setdevice(Arg4, Arg5)) Local2:= Local1:reportname() if (Local1:process()) if (Arg3 .AND. file(Arg2 + ".prn")) edittext(Arg2 + ".prn", Local2 + Space(10) + Arg1, ; Arg6) endif endif endif showmessag() return endif endif ********************************

Pasha: А какого именно метода не хватает ? Метод TPrinter:Load как раз есть

yukirin: забыл сообщение.... а возможности проверить нет. но ругань идет на (если память не изменяет) lloaderro . На LOAD не ругаемся уже. Точнее не скажу... только вечером. 3-я строка TPRNLOAD. Вечером попробую дописать там букву 'r'.

Pasha: Понятно. Это связано с органичением длины символов в клиппере 10 знаков, и легко лечится. Вызовы типа Lodal1:lloaderro надо заменить: Local1:lloaderro() -> Local1:lloaderror Local1:lloaderro(.T.) -> Local1:lloaderror := .T. Local1:lloaderro(.F.) -> Local1:lloaderror := .F.

yukirin: Здравствуйте. Продолжаю мучить программу и вот вылезла интересная ошибка... ошибка лезет из класса TPRINTER. Кормом для этого класса являются текстовые файлы типа: #Абоненты var Sum,ItGaz,kodk1,mNaimg,nom KOLSTR=60 RULON=Да DEVICE=abonement EJECT=&l0H TITUL ОТЧЕТ ПО АБОНЕМЕНТАМ ПЕРИОД С @{dtoc(mD1)+' ПО '+dtoc(mD2)} ENDTITUL MAINFOOT Итого @{str(Sum,9)} @{saytime()} 1/A/2 ENDMAINFOOT PAGEHEAD ----------------------T----------T----------¬ ¦ Наименование ¦Код киоска¦Количество¦ +---------------------+----------+----------+ ENDPAGEHEAD PAGEFOOT L---------------------+----------+----------- ENDPAGEFOOT @ Sum:=0 @ dbSelectArea('tmp') @ dbGoTop() @ while !eof() @ itGaz:=0 @ mNaimg:=tmp->naimg @ nom:=0 @ while mNaimg=tmp->naimg @ if tmp->kol#0 @ nom:=nom+1 $@{' | '+if(nom=1,tmp->naimg,space(len(tmp->naimg)))+'| '+str(tmp->kodk,4)+' | '+str(tmp->kol,4)+' |'} @ ItGaz:=ItGaz+tmp->kol @ Sum:=Sum+tmp->kol @ endif @ dbSkip() @ endwhile @ if nom>1 $@{' | Итого '+space(28)+str(ItGaz,4)+' |'} @ endif itGaz#0 @ if NOM>0.AND.!eof() +---------------------+----------+----------+ @ endif @ endwhile Эти файлы обрабатываются методом TPRNLOAD приведенный в 15 посте(аргументом ARG1 для него будет путь к файлу). По ходу выполнения этого метода заполняется массив tprinter::aopr. В него заносятся строки кода, которые потом динамически будут выполняться. Есть один отчет (вернее разнарядка) на которой программа вываливается с сообщение об ошибке - BASE/1449 Syntax error: &. Ошибка возникает в строке otherwise AAdd(Local1:aopr, {"OP", Local7, Local5, 0, &("{||" + Local7 + "}")}) // при выполнении этой строки endcase метода TPRNLOAD, при обработке строки текстового файла отчета - var nSel,tmp,i,kolrec,cString,KolGor,Kol,SumR,SumO var aKodRaion,aNamRaion,aSumRaion,j,Sum,aSumRAll #,part var zagol,zagol1,zagol2,zagol3,zagol4,aCena,aKol,aKolO,cString1,kolrec1,SumAllG,SumAllO #Печать разнарядки на город @1=dtoc(rrh0->date) @2=trim(rrh0->time) @3=alltrim(str(rrh0->NomRasn,3)) @4='('+trim(rrh0->prim)+')' KOLSTR=55 RULON=Нет EJECT=&l0H Ustanovki=&l1O(s12H&l8D LIST=Нет #mod(oPrn:nList,2) PAGEHEAD Р А З Н А Р Я Д К А N @3 @1 @4 лист @{str(oPrn:nList,3)} часть @{str(part,2)} @{saytime()} 1/3/2/Enter/F5 @{if(oPrn:nList%2=0,chr(13)+chr(10)+zagol,'')} ENDPAGEHEAD @ part:=1 @ SumAllO:=0 @ SumAllG:=0 @ aKodRaion:={} @ aNamRaion:={} @ aSumRaion:={} @ aSumRAll:={} @ aCena:={} @ zagol:='' @ dbSelectArea('raig') @ dbGoTop() @ while !eof() @ aAdd(aKodRaion,raig->kodr) @ aAdd(aNamRaion,raig->naim) @ aAdd(aSumRaion,0) @ aAdd(aSumRAll,0) @ dbSkip() @ endwhile @ while !empty(aLockList) @ dbSelectArea('rrh') @ kolrec:=len(aLockList) @ aKol:=array(kolrec) @ aKolO:=array(kolrec) @ aFill(aKol,0) @ aFill(aKolO,0) @ Zagol1:=' РАЙОН:' @ Zagol2:=' :' @ Zagol3:=' :' @ Zagol4:=' :' @ i:=1 @ aFill(aSumRaion,0) @ while i<=kolrec.and.i<=9 @ dbGoTo(aLockList) @ Zagol1:=Zagol1+rrh->nnom+':' @ Zagol2:=Zagol2+padr(rrh->naimg,13)+':' @ Zagol3:=Zagol3+padr(substr(rrh->naimg,14),13)+':' @ Zagol4:=Zagol4+str(rrh->rcena,8,2)+' :' @ aAdd(aCena,rrh->rcena) @ i:=i+1 @ endwhile @ kolrec1:=i-1 @ if part>1 @ oPrn:NewPage() @ endif ------------------------------------------------------------------------------------------------------------------------------------ $@{zagol1} ------------------------------------------------------------------------------------------------------------------------------------ $@{zagol2} $@{zagol3} ------------------------------------------------------------------------------------------------------------------------------------ $@{zagol4} ------------------------------------------------------------------------------------------------------------------------------------ @ zagol:=' ------------------------------------------------------------------------------------------------------------------------------------'+chr(13)+chr(10) @ zagol:=zagol+zagol1+chr(13)+chr(10) @ zagol:=zagol+' ------------------------------------------------------------------------------------------------------------------------------------'+chr(13)+chr(10) @ zagol:=zagol+zagol2+chr(13)+chr(10) @ zagol:=zagol+zagol3+chr(13)+chr(10) @ zagol:=zagol+' ------------------------------------------------------------------------------------------------------------------------------------'+chr(13)+chr(10) @ zagol:=zagol+zagol4+chr(13)+chr(10) @ zagol:=zagol+' ------------------------------------------------------------------------------------------------------------------------------------' @ dbSelectArea('raig') @ dbGoTop() @ j:=1 @ while !eof() @ cString:=padr(raig->naim,8) @ i:=1 @ if raig->type='G' @ while i<=kolrec1 @ rrh->(dbGoTo(aLockList)) // ПРИ ОБРАБОТКЕ ЭТОЙ СТРОКИ МЫ ОШИБАЕМСЯ @ if rrd->(dbSeek(str(rrh0->NomRasn,3)+Upper(rrh->naimg)+rrh->nnom+'G'+str(raig->kodr,3))) @ cString:=cString+str(rrd->prihod,6)+' ' @ else @ cString:=cString+str(0,6)+' ' @ endif Причем до этого момента элементы в массив добавлялись исправно не один десяток раз ( точнее 68), а при добавлении 69-го элемента массива tprinter::aopr получаю ошибку..... . Существуют ли какие либо ограничения на размер массива в клиппере ? если есть как их преодолеть ? Если ограничений нет - то подскажите пожалуйста возможные причины возникновения данной ошибки. И еще один вопрос. Как мне включить(прилинковать) в ЕХЕ модуль функцию/процедуру явно не использующуюся в программе, но присутствующую во внешнем текстовом файле и, соответственно, выполняющуюся динамически. Например - SwpRunCmd().

alkresin: Существуют ли какие либо ограничения на размер массива в клиппере ? 4096 элементов. И еще один вопрос. Как мне включить(прилинковать) в ЕХЕ модуль функцию/процедуру явно не использующуюся в программе, но присутствующую во внешнем текстовом файле и, соответственно, выполняющуюся динамически. Например - SwpRunCmd(). Вставьте в текст программы REQUEST SwpRunCmd

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

yukirin: Прошел отладчиком до момента возникновения ошибки - Local5 := 114 local7:= "rrh->(dbGoTo(aLockList))" итоговая команда получается: aadd( Local1:aopr, {"OP", "rrh->(dbGoTo(aLockList))", 114, 0, &("{||rrh->(dbGoTo(aLockList))}")} ) я в ней ничего криминального не вижу. Но нажимаем F8 и получаем BASE\1449 (((((( Завтра попробую увеличить количество строк в каком-нибудь нормально работающем отчете что бы превысить порог в 68 элементов...

yukirin: Съедаются квадратные скобки.....после aLockList квадратные скобки с буковкой - i

yukirin: читаю про & и ->... Пока как-то туговато...англицкий все-таки.... Что же такого неправильного в строке [pre]rrh->(dbGoTo(aLockList[i]))[/pre] Оригинальный экзешник все проглатывает на ура... Есть ли на русском CA-Clipper 5.2 Norton Guide?

alkresin: & - оператор, предписывающий макрокомпилятору ( встроенное в ваше прилжение средство ) откомпилировать следующую за & строку. Ошибка BASE 1449 говорит, что эта строка не есть правильное выражение. В строке все правильно. Попробуйте поэкспериментировать с ней - написать что-нибудь другое, от простейшего - к сложному. На русском есть NG к 5.1

nick_mi: А что хранится в aLockList? Посмотрите его содержимое

alkresin: nick_mi пишет: А что хранится в aLockList? Посмотрите его содержимое Не думаю, что это имеет значение. Программа ругается на компиляцию строки, а не на выполнение скомпилированного кода, на этой стадии не имеет значения, что содержит aLockList и даже, существует ли он вообще. У меня такое ощущение, что проблема там не в конкретной компилируемой строчке, а в чем-то другом. Может, памяти не хватает, или еще каких-нибудь ресурсов. Для больших программ на Клиппере, насколько я помню, имело значение, как они разбиты на модули, как и чем собраны, с какими опциями линкера. Overlays и все такое ...

yukirin: Это единственная форма которая формируется с ошибкой. Другие два десятка форм формируются нормально. В этом же документе(в этом текстовом файле) эта строка появляется два раза. Исключаю первое появление... спотыкаемся на втором...исключаю второе- сканируем текст файла до конца без вываливаний... Т.е. получается память непричем. А именно не нравится синтаксис строки. О как. ладно оставлю до понедельника.... надо отдохнуть.

User216: Попробуйте для линковки RTLINK или EXOSPACE. Может поможет...?

yukirin: Проблему с неправильной обработкой строки отложил т.к. наткнулся на другую проблему созвучную, видимо, с этой. Для просмотра табличных данных в программе иногда используется следующий экземпляр TBrowse [pre2] #include "Set.ch" #include "common.ch" ******************************** function TBROWSEIND(Arg1, Arg2, Arg3, Arg4, Arg5) local Local1 Local1:= tbrowsenew(Arg1, Arg2, Arg3, Arg4) Local1:goTopBlock({|BL| BL:= Set(_SET_SOFTSEEK, .T.), dbSeek(Arg5), Set(_SET_SOFTSEEK, BL)}) Local1:goBottomBlock({|| GotoBottom(Arg5)}) Local1:skipBlock({|BL| MovePointer(BL, Arg5)}) return Local1 ******************************** static function MovePointer(Arg1, Arg2) local Local1:= 0 if (Arg1 == 0) skip 0 else do while (!BOF() .AND. !EOF() .AND. Local1 != Arg1 .AND. &(indexkey()) = Arg2) dbSkip(if(Arg1 < 0, ( Local1--, -1 ), ( Local1++, 1 ))) enddo if (BOF()) // это 24-я строка Local1++ elseif (EOF()) skip -1 Local1-- elseif (!(&(indexkey()) = Arg2)) dbSkip(if(Arg1 > 0, ( Local1--, -1 ), ( Local1++, 1 ))) endif endif return Local1 ******************************** static procedure GotoBottom(Arg1) if (Len(Arg1) == 0) goto bottom else seek SubStr(Arg1, 1, Len(Arg1) - 1) + Chr(Asc(SubStr(Arg1, ; Len(Arg1))) + 1) softseek skip -1 endif ********************************[/pre2] Так вот при перемещении по таблице вверх/вниз периодически программа вываливается все с тем же сообщением BASE/1449 Syntax error: &. Только на сей раз это происходит в неопределенный момент времени и положения курсора в таблице. После перезапуска программы ошибка возникает в другом месте...Там же где ошибка возникла перемещаемся без ошибок. Восстановил процедуру логгирования ошибок. Вот его сообщения: [pre2]Ошибка BASE/1449 Ошибка в синтаксисе: & Вызов из LOCKERRHAN(0) Вызов из (b)INITHANDL$(0) Вызов из MOVEPOINTE(24) Вызов из (b)TBROWSEIND(11) Вызов из obj:FORCESTABL(0) Вызов из DOCUM(2640) Вызов из (b)VOZVMNU(5167) Вызов из PROCESSMEN(4688) Вызов из VOZVMNU(5182) Вызов из (b)MAIN(190) Вызов из PROCESSMEN(4688) Вызов из MAIN(205) Вызов из TORG_1(18)[/pre2] Ошибка всегда идет из ф-ции MovePointer, и почти всегда из 24-ой строки(иногда 21 проскакивает). Подскажите ПЛИЗ что это может значить и куда копать.....

petr707: Может быть "плохой" индекс - не соотв.таблице. При перемещении по таблице перевычисляется &(indexkey()) или само выражение indexkey() - некорректное Если в индексе нет UDF - можно открыть таблицу с индексом другой утилитой ,(м.б. DBU или подобной)

Pasha: Поиск по гуглу дает ссылки на возгласы отчаянья и шаманские пляски: https://groups.google.com/forum/?fromgroups#!search/BASE$2F1449$20/comp.lang.clipper/OkS4YkJgBow/dvzksrCYIjoJ https://groups.google.com/forum/?fromgroups#!search/BASE$2F1449$20/relcom.comp.dbms.clipper/7qt5dv376o4/oFuIXfgZ_TsJ

Pasha: 10 лет назад в результате плясок с бубном предположили причину этой ошибки, см. ниже. Это связано с какими-то ограничениями по памяти, в результате которых падает макрокомпилятор. Возможно, стоит увеличить размер стека при сборке программы. Это команда блинкера: STACK NNNN Вот это сообщение: http://computer-programming-forum.com/19-clipper/0ecf86730f10b247.htm I have had syntax errors with & when my app was trying to macro expand a string that had an expression. It was a perfectly good string which should not have generated a syntax error. I have a very large app which still has probably 500 private vars. I found that by changing some of the privates to locals and making appropriate code changes caused the syntax error to disappear. There seems to be a limit to how many privates the eval stack can hold and when this is reached, the macro compiler goes crazy. If your app does not have alot of private vars, then my advice is probably not applicable.

petr707: Можно создать блок кода для indexkey() и уменьшить таким образом число макровычислений. #define COMPILE(x) &("{||"+x+"}") ... //Модифицировать код static function MovePointer(Arg1, Arg2) Local block:=COMPILE(indexkey()) ... // далее по тексту замена &(indexkey()) на eval(block) полученные выражение вида DBSKIP(if(Arg1 < 0, ( Local1--, -1 ), ( Local1++, 1 ))) лучше упростить if Arg1 < 0 n:=-1 Local1-- else n:= 1 Local++ endif dbskip(n)

yukirin: Приватных переменных действительно много.... Буду смотреть что можно сделать в этой ситуации... Сделал одно наблюдение что введение в скрипт линкера строки BLINKER OVERLAY OPSIZE 128 - в разы увеличивает время работы программы до краха(BASE/1449). Такое ощущение что где-то происходит утечка памяти... Еще объясните пожалуйста что в этом блоке кода может быть неправильно: [pre2] static SetStack := {} . . . procedure SaveSet() memvar SetStack AAdd(SetStack, {Select(), indexord(), RecNo()}) ******************************** procedure RestoreSet() memvar SetStack local length:= Len(SetStack) if (length > 0) select (SetStack[length, 1]) set order to SetStack[length, 2] go SetStack[length, 3] endif aSize(SetStack, length - 1) ******************************** [/pre2] При первом же вызове SaveSet() получаю что переменная SETSTACK не существует petr707 - Ваши предложения попробую позже..Что то у нас сбербанк онлайн не хочет онлайнить.....

alkresin: Строчка "memvar SetStack" в начале процедуры означает, что в этой процедуре предполагается, что SetStack - это именно memvar, т.е. Private или Public переменная. Если такой нет, то вы получаете то, что получили ... Переменная, описаннпя как Static - это не memvar. Теоретически можно предположить, что где-то должна быть объявлена и Public/Private с тем же именем и эти процедуры обращаются именно к ней, но, скорее всего, здесь просто ошибка. Так что или сделайте эту SetStack Public/Private, или уберите ее объявления как memvar.

yukirin: Без мемвар я получаю предепреждения Warning C1003 Ambiguous reference: 'SETSTACK', поэтому и поставил мемвар. Но и с мемвар и без получаю данную ошибку.... Насколько я понимаю область видимости данной переменной распространяется на весь данный файл. Предположить что это имя уже используется... обозвал её StTorgSt - получил что нет такой перемененной..... бред какой-то....

alkresin: Да, область видимости static переменной, объявленной вне какой-либо процедуры, распространяется на весь файл. А точно у вас эта Setstack объявлена вне процедур ?

yukirin: абсолютно точно вне процедур. переписал так: [pre2] procedure SaveSet() public StTorgSt := {} AAdd(StTorgSt, {Select(), indexord(), RecNo()}) ******************************** procedure RestoreSet() local length:= Len(StTorgSt) if (length > 0) select (StTorgSt[length, 1]) set order to StTorgSt[length, 2] go StTorgSt[length, 3] endif aSize(StTorgSt, length - 1) ******************************** [/pre2] программа на отсутствие не ругается, но и работает не правильно...

yukirin: есть третий вариант.... [pre2] function SaveSet() static StTorgSt := {} AAdd(StTorgSt, {Select(), indexord(), RecNo()}) return StTorgSt ******************************** procedure RestoreSet(Arg1) local length:= Len(Arg1) if (length > 0) select (Arg1[length, 1]) set order to Arg1[length, 2] go Arg1[length, 3] endif aSize(Arg1, length - 1) ********************************[/pre2] Возвращаем StTorgSt и потом передаем её в RestoreSet Так работает.... Но.... почему первый вариант не работоспособен

alkresin: А другие static переменные работают нормально, или там только SetStack объявлена ?

alkresin: И еще, файл компилируется с ключом /n ?

yukirin: строка вызова компилятора: clipper name_file /b /m /w >1.log перенес эти две процедуры в другой модуль [pre2] #include "Set.ch" #include "common.ch" #include "inkey.ch" static SetStack:={}, Static37, Static38, Static39, Static40, Static41, Static42 static Static2, Static3, Static4, Static5, Static7 ******************************** procedure SaveSet() AAdd(SetStack, {Select(), indexord(), RecNo()}) ******************************** procedure RestoreSet() local length:= Len(SetStack) if (length > 0) select (SetStack[length, 1]) set order to SetStack[length, 2] go SetStack[length, 3] endif aSize(SetStack, length - 1) ******************************** function GETSECRET(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) local Local1:= Row(), Local2:= Col(), Local3[1], Local4 Static38:= iif(Arg2 = Nil, Local1, Arg2) Static39:= iif(Arg3 = Nil, Local2, Arg3) if (Arg4 = Nil) Arg4:= .F. endif SetPos(Static38, Static39) if (Arg5 != Nil) dispout(Arg5) Static39:= Col() + 1 SetPos(Static38, Static39) endif if (csetdeli()) Static39++ endif Static37:= Arg1 Local3[1]:= __Get({|_1| iif(ISNIL(_1), Static37, Static37:= _1)}, ; "_CGETSECRET", Arg6, Arg7, Arg8) Local3[1]:row(255) Static40:= Local3[1] Static42:= wselect() Static41:= MaxCol() + 1 - Static39 Local4:= trapinput("_SECRET") ReadModal(Local3) trapinput(Local4) if (!Arg4) unselected() endif @ Static38, Static39 say rangerepl(33, 31, Static37, "*") standard() SetPos(Local1, Local2) return Static37 ******************************** procedure _SECRET local Local1 if (wselect() = Static42 .AND. readvar() == "_CGETSECRET") Static40:assign() Local1:= dsetwindow(.T.) sayscreen(rangerepl(33, 31, Left(Static37, Static41), "*"), ; Static38, Static39) dsetwindow(Local1) SetPos(Static38, Col()) endif return ********************************[/pre2] НЕТ ТАКОЙ ПЕРЕМЕННОЙ....Хотя рядом статические переменные которые используются в ф-циях ввода пароля....Пароль же я ввожу при входе в программу и там все нормально.

alkresin: Чтобы статические переменные, объявленные вне процедур, были видны, надо при компиляции добавить ключ /n

yukirin: alkresin - СПАСИБО. Век живи век учись. Одной проблемой стало меньше.

yukirin: Перевел проект на xHarbour. Появилась стабильность. Доработал печать... Прощай LPT. Появилась возможность запускть прогу под win2008 x64. После нового года буду пробовать людей сажать работать через удал. раб стол.... Красотищщааа.... Всем огромное спасибо за участие... Не прощаюсь. Вопросы все равно будут еще возникать.

Andrey: yukirin пишет: Красотищщааа.... Используй gtwvt-терминал. Там можно будет свои шрифты настраивать и регулировать размер задачи на экране. Смотри тему http://clipper.borda.ru/?1-4-0-00000624-000-40-0-1356073627 ищи фразу: GTWVT-терминал "Настройка палитры/шрифтов/размеров экрана" for xHarbour 1.2 !



полная версия страницы