My bad, thank you, I've found now this code inside the package. Converting from VB to Harbour is simple s&r for the most part.
Brgds, Viktor On 2010 Feb 5, at 13:07, Massimo Belgrano wrote: > Here is visual basic part > good for you a way like > oPrn := win_prn():New(GetDefaultPrinter()) > oPrn:SetFont("code128",11,,,,255) // please try different value > oPrn:TextOut(pdf417("ABC"),.t.) > oPrn:NewPage() > > or > oPrinter := xbpPrinter():New():Create(cPrinter, PRN_Q_TEXT ) > > > Private Function pdf417$(Chaine$, Optional ByRef sécu%, Optional ByRef > nbcol%, Optional ByRef CodeErr%) > 'V 1.5.0 > 'Paramètres : Une chaine à encoder > ' Le niveau de correction souhaité, -1 = automatique. > ' Le nombre de colonnes de MC de données souhaité, -1 = > automatique > ' Une variable qui pourra récupérer un numéro d'erreur > 'Retour : * une chaine qui, affichée avec la police PDF417.TTF, > donne le code barre > ' * une chaine vide si paramètre fourni incorrect > ' * Sécu% contient le niveau de correction effectif > ' * NbCol% contient le nombre de colonnes de MC de données effectif > ' * Codeerr% contient 0 si pas d'erreur, sinon : > ' 0 : Pas d'erreur > ' 1 : Chaine$ est vide > ' 2 : Chaine$ contient trop de données, on dépasse le > nombre de 928 MC. > ' 3 : Nombre de MC par ligne trop faible, on dépasse 90 lignes. > ' 10 : Le niveau de sécurité a été abaissé pour ne pas > dépasser les 928 MC. > > 'Parameters : The string to encode. > ' The hoped sécurity level, -1 = automatic. > ' The hoped number of data MC columns, -1 = automatic. > ' A variable which will can retrieve an error number. > 'Return : * a string which, printed with the PDF417.TTF font, gives > the bar code. > ' * an empty string if the given parameters aren't good. > ' * sécu% contain le really used sécurity level. > ' * NbCol% contain the really used number of data CW columns. > ' * Codeerr% is 0 if no error occured, else : > ' 0 : No error > ' 1 : Chaine$ is empty > ' 2 : Chaine$ contain too many datas, we go beyong the 928 CWs. > ' 3 : Number of CWs per row too small, we go beyong 90 rows. > ' 10 : The sécurity level has being lowers not to exceed > the 928 CWs. (It's not an error, only a warning.) > > 'Variables générales / Global variables > Dim I%, J%, K%, IndexChaine%, Dummy$, flag As Boolean > 'Découpage en blocs / Splitting into blocks > Dim Liste%(), IndexListe% > 'Compactage des données / Data compaction > Dim Longueur%, ChaineMC$, Total > 'Traitement du mode "texte" / "text" mode processing > Dim ListeT%(), IndexListeT%, CurTable%, ChaineT$, NewTable% > 'Codes de Reed Solomon / Reed Solomon codes > Dim MCcorrection%() > 'MC de cotés gauche et droit / Left and right side CWs > Dim C1%, C2%, C3% > 'Sous programme QuelMode / Sub routine QuelMode > Dim Mode%, CodeASCII% > 'Sous programme Modulo / Sub routine Modulo > Dim ChaineMod$, Diviseur&, ChaineMult$, Nombre& > 'Tables > Dim ASCII$ > 'Cette chaine décrit le code ASCII pour le mode "texte". > 'ASCII$ contient 95 champs de 4 chiffres correspondant aux car. de > valeur ASCII 32 à 126. Les champs sont : > ' 2 chiffres indiquant la ou les tables où se trouvent ce car. > (Tables numérotées 1, 2, 4 et 8) > ' 2 chiffres indiquant le N° du car. dans la table > ' Ex. 0726 en début de chaine : le car. de code 32 est dans les > tables 1, 2 et 4 à la ligne 26 > ' > 'This string describe the ASCII code for the "text" mode. > 'ASCII$ contain 95 fields of 4 digits which correspond to char. > ASCII values 32 to 126. These fields are : > ' 2 digits indicating the table(s) (1 or several) where this char. > is located. (Table numbers : 1, 2, 4 and 8) > ' 2 digits indicating the char. number in the table > ' Sample : 0726 at the beginning of the string : The Char. having > code 32 is in the tables 1, 2 and 4 at row 26 > ASCII$ = > "07260810082004151218042104100828082308241222042012131216121712190400040104020403040404050406040704080409121408000801042308020825080301000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125080408050806042408070808020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250826082108270809" > Dim CoefRS$(8) > 'CoefRS$ contient 8 chaines représentant les coefficients sur 3 > chiffres des polynomes de calcul des codes de reed Solomon > 'CoefRS$ contain 8 strings describing the factors of the polynomial > equations for the reed Solomon codes. > CoefRS$(0) = "027917" > CoefRS$(1) = "522568723809" > CoefRS$(2) = "237308436284646653428379" > CoefRS$(3) = "274562232755599524801132295116442428295042176065" > CoefRS$(4) = > "361575922525176586640321536742677742687284193517273494263147593800571320803133231390685330063410" > CoefRS$(5) = > "539422006093862771453106610287107505733877381612723476462172430609858822543376511400672762283184440035519031460594225535517352605158651201488502648733717083404097280771840629004381843623264543" > CoefRS$(6) = > "521310864547858580296379053779897444400925749415822093217208928244583620246148447631292908490704516258457907594723674292272096684432686606860569193219129186236287192775278173040379712463646776171491297763156732095270447090507048228821808898784663627378382262380602754336089614087432670616157374242726600269375898845454354130814587804034211330539297827865037517834315550086801004108539" > CoefRS$(7) = > "524894075766882857074204082586708250905786138720858194311913275190375850438733194280201280828757710814919089068569011204796605540913801700799137439418592668353859370694325240216257284549209884315070329793490274877162749812684461334376849521307291803712019358399908103511051008517225289470637731066255917269463830730433848585136538906090002290743199655903329049802580355588188462010134628320479130739071263318374601192605142673687234722384177752607640455193689707805641048060732621895544261852655309697755756060231773434421726528503118049795032144500238836394280566319009647550073914342126032681331792620060609441180791893754605383228749760213054297134054834299922191910532609829189020167029872449083402041656505579481173404251688095497555642543307159924558648055497010" > CoefRS$(8) = > "352077373504035599428207409574118498285380350492197265920155914299229643294871306088087193352781846075327520435543203666249346781621640268794534539781408390644102476499290632545037858916552041542289122272383800485098752472761107784860658741290204681407855085099062482180020297451593913142808684287536561076653899729567744390513192516258240518794395768848051610384168190826328596786303570381415641156237151429531207676710089168304402040708575162864229065861841512164477221092358785288357850836827736707094008494114521002499851543152729771095248361578323856797289051684466533820669045902452167342244173035463651051699591452578037124298332552043427119662777475850764364578911283711472420245288594394511327589777699688043408842383721521560644714559062145873663713159672729" > CoefRS$(8) = CoefRS$(8) & > "624059193417158209563564343693109608563365181772677310248353708410579870617841632860289536035777618586424833077597346269757632695751331247184045787680018066407369054492228613830922437519644905789420305441207300892827141537381662513056252341242797838837720224307631061087560310756665397808851309473795378031647915459806590731425216548249321881699535673782210815905303843922281073469791660162498308155422907817187062016425535336286437375273610296183923116667751353062366691379687842037357720742330005039923311424242749321054669316342299534105667488640672576540316486721610046656447171616464190531297321762752533175134014381433717045111020596284736138646411877669141919045780407164332899165726600325498655357752768223849647063310863251366304282738675410389244031121303263" > Dim CodageMC$(2) > 'CodageMC$ contient les 3 jeux des 929 MC. Chaque MC est représenté > dans la police PDF417.TTF par 3 lettres composant 3 fois 5 bits. Le > premier bit toujours à 1 > ' et le dernier toujours à 0 se trouvent dans le caractère séparateur. > 'CodageMC$ contain the 3 sets of the 929 MCs. Each MC is described > in the PDF417.TTF font by 3 char. composing 3 time 5 bits. The first > bit which is always 1 > ' and the last one which is always 0 are into the separator character. > CodageMC$(0) = > "urAxfsypyunkxdwyozpDAulspBkeBApAseAkprAuvsxhypnkutwxgzfDAplsfBkfrApvsuxyfnkptwuwzflspsyfvspxyftwpwzfxyyrxufkxFwymzonAudsxEyolkucwdBAoksucidAkokgdAcovkuhwxazdnAotsugydlkoswugjdksosidvkoxwuizdtsowydswowjdxwoyzdwydwjofAuFsxCyodkuEwxCjclAocsuEickkocgckcckEcvAohsuayctkogwuajcssogicsgcsacxsoiycwwoijcwicyyoFkuCwxBjcdAoEsuCicckoEguCbcccoEaccEoEDchkoawuDjcgsoaicggoabcgacgDobjcibcFAoCsuBicEkoCguBbcEcoCacEEoCDcECcascagcaacCkuAroBaoBDcCBtfkwpwyezmnAtdswoymlktcwwojFBAmksFAkmvkthwwqzFnAmtstgyFlkmswFksFkgFvkmxwtizFtsmwyFswFsiFxwmyzFwyFyzvfAxpsyuyvdkxowyujqlAvcsxoiqkkvcgxobqkcvcamfAtFswmyqvAmdktEwwmjqtkvgwxqjhlAEkkmcgtEbhkkqsghkcEvAmhstayhvAEtkmgwtajhtkqwwvijhssEsghsgExsmiyhxsEwwmijhwwqyjhwiEyyhyyEyjhyjvFkxmwytjqdAvEsxmiqckvEgxmbqccvEaqcEqcCmFktCwwljqhkmEstCigtAEckvaitCbgskEccmEagscqgamEDEcCEhkmawtDjgxkEgsmaigwsqiimabgwgEgaEgDEiwmbjgywEiigyiEibgybgzjqFAvCsxliqEkvCgxlbqEcvCaqEEvCDqECqEBEFAmCstBighAEEkmCgtBbggkqagvDbggcEEEmCDggEqaDgg" > CodageMC$(0) = CodageMC$(0) & > "CEasmDigisEagmDbgigqbbgiaEaDgiDgjigjbqCkvBgxkrqCcvBaqCEvBDqCCqCBECkmBgtArgakECcmBagacqDamBDgaEECCgaCECBEDggbggbagbDvAqvAnqBBmAqEBEgDEgDCgDBlfAspsweyldksowClAlcssoiCkklcgCkcCkECvAlhssqyCtklgwsqjCsslgiCsgCsaCxsliyCwwlijCwiCyyCyjtpkwuwyhjndAtoswuincktogwubncctoancEtoDlFksmwwdjnhklEssmiatACcktqismbaskngglEaascCcEasEChklawsnjaxkCgstrjawsniilabawgCgaawaCiwlbjaywCiiayiCibCjjazjvpAxusyxivokxugyxbvocxuavoExuDvoCnFAtmswtirhAnEkxviwtbrgkvqgxvbrgcnEEtmDrgEvqDnEBCFAlCssliahACEklCgslbixAagknagtnbiwkrigvrblCDiwcagEnaDiwECEBCaslDiaisCaglDbiysaignbbiygrjbCaDaiDCbiajiCbbiziajbvmkxtgywrvmcxtavmExtDvmCvmBnCktlgwsrraknCcxtrracvnatlDraEnCCraCnCBraBCCklBgskraakCCclBaiikaacnDalBDiicrbaCCCiiEaaCCCBaaBCDglBrabgCDaijgabaCDDijaabDCDrijrvlcxsqvlExsnvlCvlBnBctkqrDcnBEtknrDEvlnrDCnBBrDBCBclAqaDcCBElAnibcaDEnBnibErDnCBBibCaDBibBaDqibqibnxsfvkltkfnAmnAlCAoaBoiDoCAlaBlkpkBdAkosBckkogsebBcckoaBcEkoDBhkkqwsfjBgskqiBggkqbBgaBgDBiwkrjBiiBibBjjlpAsuswhil" > CodageMC$(0) = CodageMC$(0) & > "oksuglocsualoEsuDloCBFAkmssdiDhABEksvisdbDgklqgsvbDgcBEEkmDDgElqDBEBBaskniDisBagknbDiglrbDiaBaDBbiDjiBbbDjbtukwxgyirtucwxatuEwxDtuCtuBlmkstgnqklmcstanqctvastDnqElmCnqClmBnqBBCkklgDakBCcstrbikDaclnaklDbicnraBCCbiEDaCBCBDaBBDgklrDbgBDabjgDbaBDDbjaDbDBDrDbrbjrxxcyyqxxEyynxxCxxBttcwwqvvcxxqwwnvvExxnvvCttBvvBllcssqnncllEssnrrcnnEttnrrEvvnllBrrCnnBrrBBBckkqDDcBBEkknbbcDDEllnjjcbbEnnnBBBjjErrnDDBjjCBBqDDqBBnbbqDDnjjqbbnjjnxwoyyfxwmxwltsowwfvtoxwvvtmtslvtllkossfnlolkmrnonlmlklrnmnllrnlBAokkfDBolkvbDoDBmBAljbobDmDBljbmbDljblDBvjbvxwdvsuvstnkurlurltDAubBujDujDtApAAokkegAocAoEAoCAqsAqgAqaAqDAriArbkukkucshakuEshDkuCkuBAmkkdgBqkkvgkdaBqckvaBqEkvDBqCAmBBqBAngkdrBrgkvrBraAnDBrDAnrBrrsxcsxEsxCsxBktclvcsxqsgnlvEsxnlvCktBlvBAlcBncAlEkcnDrcBnEAlCDrEBnCAlBDrCBnBAlqBnqAlnDrqBnnDrnwyowymwylswotxowyvtxmswltxlksosgfltoswvnvoltmkslnvmltlnvlAkokcfBloksvDnoBlmAklbroDnmBllbrmDnlAkvBlvDnvbrvyzeyzdwyexyuwydxytswetwuswdvxutwtvxtkselsuksdntulstrvu" > CodageMC$(1) = > "ypkzewxdAyoszeixckyogzebxccyoaxcEyoDxcCxhkyqwzfjutAxgsyqiuskxggyqbuscxgausExgDusCuxkxiwyrjptAuwsxiipskuwgxibpscuwapsEuwDpsCpxkuywxjjftApwsuyifskpwguybfscpwafsEpwDfxkpywuzjfwspyifwgpybfwafywpzjfyifybxFAymszdixEkymgzdbxEcymaxEEymDxECxEBuhAxasyniugkxagynbugcxaaugExaDugCugBoxAuisxbiowkuigxbbowcuiaowEuiDowCowBdxAoysujidwkoygujbdwcoyadwEoyDdwCdysozidygozbdyadyDdzidzbxCkylgzcrxCcylaxCEylDxCCxCBuakxDgylruacxDauaExDDuaCuaBoikubgxDroicubaoiEubDoiCoiBcykojgubrcycojacyEojDcyCcyBczgojrczaczDczrxBcykqxBEyknxBCxBBuDcxBquDExBnuDCuDBobcuDqobEuDnobCobBcjcobqcjEobncjCcjBcjqcjnxAoykfxAmxAluBoxAvuBmuBloDouBvoDmoDlcbooDvcbmcblxAexAduAuuAtoBuoBtwpAyeszFiwokyegzFbwocyeawoEyeDwoCwoBthAwqsyfitgkwqgyfbtgcwqatgEwqDtgCtgBmxAtiswrimwktigwrbmwctiamwEtiDmwCmwBFxAmystjiFwkmygtjbFwcmyaFwEmyDFwCFysmziFygmzbFyaFyDFziFzbyukzhghjsyuczhahbwyuEzhDhDyyuCyuBwmkydgzErxqkwmczhrxqcyvaydDxqEwmCxqCwmBxqBtakwngydrviktacwnavicxrawnDviEtaCviCtaBviBmiktbgwnrqykmictb" > CodageMC$(1) = CodageMC$(1) & > "aqycvjatbDqyEmiCqyCmiBqyBEykmjgtbrhykEycmjahycqzamjDhyEEyChyCEyBEzgmjrhzgEzahzaEzDhzDEzrytczgqgrwytEzgngnyytCglzytBwlcycqxncwlEycnxnEytnxnCwlBxnBtDcwlqvbctDEwlnvbExnnvbCtDBvbBmbctDqqjcmbEtDnqjEvbnqjCmbBqjBEjcmbqgzcEjEmbngzEqjngzCEjBgzBEjqgzqEjngznysozgfgfyysmgdzyslwkoycfxloysvxlmwklxlltBowkvvDotBmvDmtBlvDlmDotBvqbovDvqbmmDlqblEbomDvgjoEbmgjmEblgjlEbvgjvysegFzysdwkexkuwkdxkttAuvButAtvBtmBuqDumBtqDtEDugbuEDtgbtysFwkFxkhtAhvAxmAxqBxwekyFgzCrwecyFaweEyFDweCweBsqkwfgyFrsqcwfasqEwfDsqCsqBliksrgwfrlicsraliEsrDliCliBCykljgsrrCycljaCyEljDCyCCyBCzgljrCzaCzDCzryhczaqarwyhEzananyyhCalzyhBwdcyEqwvcwdEyEnwvEyhnwvCwdBwvBsncwdqtrcsnEwdntrEwvntrCsnBtrBlbcsnqnjclbEsnnnjEtrnnjClbBnjBCjclbqazcCjElbnazEnjnazCCjBazBCjqazqCjnaznzioirsrfyziminwrdzzililyikzygozafafyyxozivivyadzyxmyglitzyxlwcoyEfwtowcmxvoyxvwclxvmwtlxvlslowcvtnoslmvrotnmsllvrmtnlvrllDoslvnbolDmrjonbmlDlrjmnblrjlCbolDvajoCbmizoajmCblizmajlizlCbvajvzieifwrFzzididyiczygeaFzywuy" > CodageMC$(1) = CodageMC$(1) & > "gdihzywtwcewsuwcdxtuwstxttskutlusktvnutltvntlBunDulBtrbunDtrbtCDuabuCDtijuabtijtziFiFyiEzygFywhwcFwshxsxskhtkxvlxlAxnBxrDxCBxaDxibxiCzwFcyCqwFEyCnwFCwFBsfcwFqsfEwFnsfCsfBkrcsfqkrEsfnkrCkrBBjckrqBjEkrnBjCBjBBjqBjnyaozDfDfyyamDdzyalwEoyCfwhowEmwhmwElwhlsdowEvsvosdmsvmsdlsvlknosdvlroknmlrmknllrlBboknvDjoBbmDjmBblDjlBbvDjvzbebfwnpzzbdbdybczyaeDFzyiuyadbhzyitwEewguwEdwxuwgtwxtscustuscttvustttvtklulnukltnrulntnrtBDuDbuBDtbjuDbtbjtjfsrpyjdwrozjcyjcjzbFbFyzjhjhybEzjgzyaFyihyyxwEFwghwwxxxxschssxttxvvxkkxllxnnxrrxBBxDDxbbxjFwrmzjEyjEjbCzjazjCyjCjjBjwCowCmwClsFowCvsFmsFlkfosFvkfmkflArokfvArmArlArvyDeBpzyDdwCewauwCdwatsEushusEtshtkdukvukdtkvtAnuBruAntBrtzDpDpyDozyDFybhwCFwahwixsEhsgxsxxkcxktxlvxAlxBnxDrxbpwnuzboybojDmzbqzjpsruyjowrujjoijobbmyjqybmjjqjjmwrtjjmijmbbljjnjjlijlbjkrsCusCtkFukFtAfuAftwDhsChsaxkExkhxAdxAvxBuzDuyDujbuwnxjbuibubDtjbvjjusrxijugrxbjuajuDbtijvibtbjvbjtgrwrjtajtDbsrjtrjsqjsnBxjDxiDxbbxgnyrbxabxDDwrbxrbwqbwn" > CodageMC$(2) = > "pjkurwejApbsunyebkpDwulzeDspByeBwzfcfjkprwzfEfbspnyzfCfDwplzzfBfByyrczfqfrwyrEzfnfnyyrCflzyrBxjcyrqxjEyrnxjCxjBuzcxjquzExjnuzCuzBpzcuzqpzEuznpzCdjAorsufydbkonwudzdDsolydBwokzdAyzdodrsovyzdmdnwotzzdldlydkzynozdvdvyynmdtzynlxboynvxbmxblujoxbvujmujlozoujvozmozlcrkofwuFzcnsodyclwoczckyckjzcucvwohzzctctycszylucxzyltxDuxDtubuubtojuojtcfsoFycdwoEzccyccjzchchycgzykxxBxuDxcFwoCzcEycEjcazcCycCjFjAmrstfyFbkmnwtdzFDsmlyFBwmkzFAyzFoFrsmvyzFmFnwmtzzFlFlyFkzyfozFvFvyyfmFtzyflwroyfvwrmwrltjowrvtjmtjlmzotjvmzmmzlqrkvfwxpzhbAqnsvdyhDkqlwvczhBsqkyhAwqkjhAiErkmfwtFzhrkEnsmdyhnsqtymczhlwEkyhkyEkjhkjzEuEvwmhzzhuzEthvwEtyzhthtyEszhszyduExzyvuydthxzyvtwnuxruwntxrttbuvjutbtvjtmjumjtgrAqfsvFygnkqdwvEzglsqcygkwqcjgkigkbEfsmFygvsEdwmEzgtwqgzgsyEcjgsjzEhEhyzgxgxyEgzgwzycxytxwlxxnxtDxvbxmbxgfkqFwvCzgdsqEygcwqEjgcigcbEFwmCzghwEEyggyEEjggjEazgizgFsqCygEwqCjgEigEbECygayECjgajgCwqBjgCigCbEBjgDjgBigBbCrklfwspzCnsldyClwlczCkyCkjzCuCvwlhzzCtCtyCszyFuCx" > CodageMC$(2) = CodageMC$(2) & > "zyFtwfuwftsrusrtljuljtarAnfstpyankndwtozalsncyakwncjakiakbCfslFyavsCdwlEzatwngzasyCcjasjzChChyzaxaxyCgzawzyExyhxwdxwvxsnxtrxlbxrfkvpwxuzinArdsvoyilkrcwvojiksrciikgrcbikaafknFwtmzivkadsnEyitsrgynEjiswaciisiacbisbCFwlCzahwCEyixwagyCEjiwyagjiwjCazaiziyzifArFsvmyidkrEwvmjicsrEiicgrEbicaicDaFsnCyihsaEwnCjigwrajigiaEbigbCCyaayCCjiiyaajiijiFkrCwvljiEsrCiiEgrCbiEaiEDaCwnBjiawaCiiaiaCbiabCBjaDjibjiCsrBiiCgrBbiCaiCDaBiiDiaBbiDbiBgrAriBaiBDaAriBriAqiAnBfskpyBdwkozBcyBcjBhyBgzyCxwFxsfxkrxDfklpwsuzDdsloyDcwlojDciDcbBFwkmzDhwBEyDgyBEjDgjBazDizbfAnpstuybdknowtujbcsnoibcgnobbcabcDDFslmybhsDEwlmjbgwDEibgiDEbbgbBCyDayBCjbiyDajbijrpkvuwxxjjdArosvuijckrogvubjccroajcEroDjcCbFknmwttjjhkbEsnmijgsrqinmbjggbEajgabEDjgDDCwlljbawDCijiwbaiDCbjiibabjibBBjDDjbbjjjjjFArmsvtijEkrmgvtbjEcrmajEErmDjECjEBbCsnlijasbCgnlbjagrnbjaabCDjaDDBibDiDBbjbibDbjbbjCkrlgvsrjCcrlajCErlDjCCjCBbBgnkrjDgbBajDabBDjDDDArbBrjDrjBcrkqjBErknjBCjBBbAqjBqbAnjBnjAorkfjAmjAlb" > CodageMC$(2) = CodageMC$(2) & > "AfjAvApwkezAoyAojAqzBpskuyBowkujBoiBobAmyBqyAmjBqjDpkluwsxjDosluiDoglubDoaDoDBmwktjDqwBmiDqiBmbDqbAljBnjDrjbpAnustxiboknugtxbbocnuaboEnuDboCboBDmsltibqsDmgltbbqgnvbbqaDmDbqDBliDniBlbbriDnbbrbrukvxgxyrrucvxaruEvxDruCruBbmkntgtwrjqkbmcntajqcrvantDjqEbmCjqCbmBjqBDlglsrbngDlajrgbnaDlDjrabnDjrDBkrDlrbnrjrrrtcvwqrtEvwnrtCrtBblcnsqjncblEnsnjnErtnjnCblBjnBDkqblqDknjnqblnjnnrsovwfrsmrslbkonsfjlobkmjlmbkljllDkfbkvjlvrsersdbkejkubkdjktAeyAejAuwkhjAuiAubAdjAvjBuskxiBugkxbBuaBuDAtiBviAtbBvbDuklxgsyrDuclxaDuElxDDuCDuBBtgkwrDvglxrDvaBtDDvDAsrBtrDvrnxctyqnxEtynnxCnxBDtclwqbvcnxqlwnbvEDtCbvCDtBbvBBsqDtqBsnbvqDtnbvnvyoxzfvymvylnwotyfrxonwmrxmnwlrxlDsolwfbtoDsmjvobtmDsljvmbtljvlBsfDsvbtvjvvvyevydnwerwunwdrwtDsebsuDsdjtubstjttvyFnwFrwhDsFbshjsxAhiAhbAxgkirAxaAxDAgrAxrBxckyqBxEkynBxCBxBAwqBxqAwnBxnlyoszflymlylBwokyfDxolyvDxmBwlDxlAwfBwvDxvtzetzdlyenyulydnytBweDwuBwdbxuDwtbxttzFlyFnyhBwFDwhbwxAiqAinAyokjfAymAylAifAyvkzekzdAyeByuAydBytszp" > CodeErr% = 0 > If Chaine$ = "" Then CodeErr% = 1: Exit Function > 'Découper la chaine en blocs de caractère de même type : numérique , > texte, octet > 'La 1ère colonne du tableau Liste% contient le nombre de caractères, > la 2ème le commutateur de mode > 'Split the string in character blocks of the same type : numeric , text, byte > 'The first column of the array Liste% contain the char. number, the > second one contain the mode switch > IndexChaine% = 1 > GoSub QuelMode > Do > ReDim Preserve Liste%(1, IndexListe%) > Liste%(1, IndexListe%) = Mode% > Do While Liste%(1, IndexListe%) = Mode% > Liste%(0, IndexListe%) = Liste%(0, IndexListe%) + 1 > IndexChaine% = IndexChaine% + 1 > If IndexChaine% > Len(Chaine$) Then Exit Do > GoSub QuelMode > Loop > IndexListe% = IndexListe% + 1 > Loop Until IndexChaine% > Len(Chaine$) > 'Ne garder le mode numérique que si c'est "rentable", sinon mode > "texte" voire "octet" > 'Les seuils de rentabilité ont étés pré-déterminés selon le mode > précédent et/ou le mode suivant > 'We retain "numeric" mode only if it's earning, else "text" mode or > even "byte" mode > 'The efficiency limits have been pre-defined according to the > previous mode and/or the next mode. > For I% = 0 To IndexListe% - 1 > If Liste%(1, I%) = 902 Then > If I% = 0 Then 'C'est le premier bloc / It's the first block > If IndexListe% > 1 Then 'et il y en a d'autres derrière / And > there is other blocks behind > If Liste%(1, I% + 1) = 900 Then > 'Premier bloc et suivi par un bloc de type "texte" / First > block and followed by a "text" type block > If Liste%(0, I%) < 8 Then Liste%(1, I%) = 900 > ElseIf Liste%(1, I% + 1) = 901 Then > 'Premier bloc et suivi par un bloc de type "octet" / First > block and followed by a "byte" type block > If Liste%(0, I%) = 1 Then Liste%(1, I%) = 901 > End If > End If > Else > 'C'est pas le premier bloc / It's not the first block > If I% = IndexListe% - 1 Then > 'C'est le dernier / It's the last one > If Liste%(1, I% - 1) = 900 Then > 'Il est précédé par un bloc de type "texte" / It's > preceded by a "text" type block > If Liste%(0, I%) < 7 Then Liste%(1, I%) = 900 > ElseIf Liste%(1, I% - 1) = 901 Then > 'Il est précédé par un bloc de type "octet" / It's > preceded by a "byte" type block > If Liste%(0, I%) = 1 Then Liste%(1, I%) = 901 > End If > Else > 'C'est pas le dernier / It's not the last block > If Liste%(1, I% - 1) = 901 And Liste%(1, I% + 1) = 901 Then > 'Encadré par des blocs de type "octet" / Framed by "byte" > type blocks > If Liste%(0, I%) < 4 Then Liste%(1, I%) = 901 > ElseIf Liste%(1, I% - 1) = 900 And Liste%(1, I% + 1) = 901 Then > 'Précédé par "texte" et suivi par "octet" (Si l'inverse > jamais intéressant de changer) > 'Preceded by "text" and followed by "byte" (If the reverse > it's never interesting to change) > If Liste%(0, I%) < 5 Then Liste%(1, I%) = 900 > ElseIf Liste%(1, I% - 1) = 900 And Liste%(1, I% + 1) = 900 Then > 'Encadré par des blocs de type "texte" / Framed by "text" > type blocks > If Liste%(0, I%) < 8 Then Liste%(1, I%) = 900 > End If > End If > End If > End If > Next > GoSub Regroupe > 'Ne garder le mode "texte" que si c'est rentable / Maintain "text" > mode only if it's earning > For I% = 0 To IndexListe% - 1 > If Liste%(1, I%) = 900 And I% > 0 Then > 'C'est pas le premier (Si 1er jamais intéressant de changer) / > It's not the first (If first, never interesting to change) > If I% = IndexListe% - 1 Then 'C'est le dernier / It's the last one > If Liste%(1, I% - 1) = 901 Then > 'Précédé par un bloc de type "octet" / It's preceded by a > "byte" type block > If Liste%(0, I%) = 1 Then Liste%(1, I%) = 901 > End If > Else > 'C'est pas le dernier / It's not the last one > If Liste%(1, I% - 1) = 901 And Liste%(1, I% + 1) = 901 Then > 'Encadré par des blocs de type "octet" / Framed by "byte" type blocks > If Liste%(0, I%) < 5 Then Liste%(1, I%) = 901 > ElseIf (Liste%(1, I% - 1) = 901 And Liste%(1, I% + 1) <> 901) > Or (Liste%(1, I% - 1) <> 901 And Liste%(1, I% + 1) = 901) Then > 'Un bloc "octet" devant ou derrière / A "byte" block ahead or behind > If Liste%(0, I%) < 3 Then Liste%(1, I%) = 901 > End If > End If > End If > Next > GoSub Regroupe > 'Maintenant on compacte les données dans les MC, les MC sont > stockées sur 3 car. dans une grande chaine : ChaineMC$ > 'Now we compress datas into the MCs, the MCs are stored in 3 char. > in a large string : ChaineMC$ > IndexChaine% = 1 > For I% = 0 To IndexListe% - 1 > 'Donc 3 modes de compactage / Thus 3 compaction modes > Select Case Liste%(1, I%) > Case 900 'Texte > ReDim ListeT%(1, Liste%(0, I%)) > 'ListeT% contiendra le numéro de table(s) et la valeur de chaque > caractère > 'Numéros de table codés sur les 4 bits de poids faibles, soit en > décimal 1, 2, 4, 8 > 'ListeT% will contain the table number(s) (1 ou several) and the > value of each char. > 'Table number encoded in the 4 less weight bits, that is in > decimal 1, 2, 4, 8 > For IndexListeT% = 0 To Liste%(0, I%) - 1 > CodeASCII% = Asc(Mid$(Chaine$, IndexChaine% + IndexListeT%, 1)) > Select Case CodeASCII% > Case 9 'HT > ListeT%(0, IndexListeT%) = 12 > ListeT%(1, IndexListeT%) = 12 > Case 10 'LF > ListeT%(0, IndexListeT%) = 8 > ListeT%(1, IndexListeT%) = 15 > Case 13 'CR > ListeT%(0, IndexListeT%) = 12 > ListeT%(1, IndexListeT%) = 11 > Case Else > ListeT%(0, IndexListeT%) = Mid$(ASCII$, CodeASCII% * 4 - 127, 2) > ListeT%(1, IndexListeT%) = Mid$(ASCII$, CodeASCII% * 4 - 125, 2) > End Select > Next > CurTable% = 1 'Table par défaut / Default table > ChaineT$ = "" > 'Les données sont stockées sur 2 car. dans la chaine TableT$ / > Datas are stored in 2 char. in the string TableT$ > For J% = 0 To Liste%(0, I%) - 1 > If (ListeT%(0, J%) And CurTable%) > 0 Then > 'Le car. est dans la table courante / The char. is in the > current table > ChaineT$ = ChaineT$ & Format(ListeT%(1, J%), "00") > Else > 'Faut changer de table / Obliged to change the table > flag = False 'True si on change de table pour un seul car. / > True if we change the table only for 1 char. > If J% = Liste%(0, I%) - 1 Then > flag = True > Else > If (ListeT%(0, J%) And ListeT%(0, J% + 1)) = 0 Then flag = > True 'Pas de table commune avec le car. suivant / No common table with > the next char. > End If > If flag Then > 'On change de table pour 1 seul car., Chercher un > commutateur fugitif > 'We change only for 1 char., Look for a temporary switch > If (ListeT%(0, J%) And 1) > 0 And CurTable% = 2 Then > 'Table 2 vers 1 pour 1 car. --> T_MAJ / Table 2 to 1 for > 1 char. --> T_UPP > ChaineT$ = ChaineT$ & "27" & Format(ListeT%(1, J%), "00") > ElseIf (ListeT%(0, J%) And 8) > 0 Then > 'Table 1 ou 2 ou 4 vers table 8 pour 1 car. --> T_PON / > Table 1 or 2 or 4 to table 8 for 1 char. --> T_PUN > ChaineT$ = ChaineT$ & "29" & Format(ListeT%(1, J%), "00") > Else > 'Pas de commutateur fugitif / No temporary switch available > flag = False > End If > End If > If Not flag Then 'On re-teste flag qui a peut-être changé > ci-dessus ! donc ELSE pas possible / We test again flag which is > perhaps changed ! Impossible tio use ELSE statement > ' > 'On doit utiliser un commutateur à basculement > 'Déterminer la nouvelle table à utiliser > 'We must use a bi-state switch > 'Looking for the new table to use > If J% = Liste%(0, I%) - 1 Then > NewTable% = ListeT%(0, J%) > Else > NewTable% = IIf((ListeT%(0, J%) And ListeT%(0, J% + 1)) > = 0, ListeT%(0, J%), ListeT%(0, J%) And ListeT%(0, J% + 1)) > End If > 'Ne garder que la première s'il y en a plusieurs de > possible / Maintain the first if several tables are possible > Select Case NewTable% > Case 3, 5, 7, 9, 11, 13, 15 > NewTable% = 1 > Case 6, 10, 14 > NewTable% = 2 > Case 12 > NewTable% = 4 > End Select > 'Choisir le commutateur, parfois il faut 2 commutateurs de > suite / Select the switch, on occasion we must use 2 switchs > consecutively > Select Case CurTable% > Case 1 > Select Case NewTable% > Case 2 > ChaineT$ = ChaineT$ & "27" > Case 4 > ChaineT$ = ChaineT$ & "28" > Case 8 > ChaineT$ = ChaineT$ & "2825" > End Select > Case 2 > Select Case NewTable% > Case 1 > ChaineT$ = ChaineT$ & "2828" > Case 4 > ChaineT$ = ChaineT$ & "28" > Case 8 > ChaineT$ = ChaineT$ & "2825" > End Select > Case 4 > Select Case NewTable% > Case 1 > ChaineT$ = ChaineT$ & "28" > Case 2 > ChaineT$ = ChaineT$ & "27" > Case 8 > ChaineT$ = ChaineT$ & "25" > End Select > Case 8 > Select Case NewTable% > Case 1 > ChaineT$ = ChaineT$ & "29" > Case 2 > ChaineT$ = ChaineT$ & "2927" > Case 4 > ChaineT$ = ChaineT$ & "2928" > End Select > End Select > CurTable% = NewTable% > ChaineT$ = ChaineT$ & Format(ListeT%(1, J%), "00") 'On > ajoute enfin le car. / At last we add the char. > End If > End If > Next > If Len(ChaineT$) Mod 4 > 0 Then ChaineT$ = ChaineT$ & "29" > 'Bourrage si nb de car. impair / Padding if number of char. is odd > 'Maintenant traduire la chaine ChaineT$ en MCs > 'Now translate the string ChaineT$ into CWs > If I% > 0 Then ChaineMC$ = ChaineMC$ & "900" 'Mettre en place le > commutateur sauf si premier bloc car mode "texte" par défaut / Set up > the switch exept for the first block because "text" is the default > For J% = 1 To Len(ChaineT$) Step 4 > ChaineMC$ = ChaineMC$ & Format(Mid$(ChaineT$, J%, 2) * 30 + > Mid$(ChaineT$, J% + 2, 2), "000") > Next > Case 901 'Octet > 'Choisir le commutateur parmi les 3 possibles / Select the > switch between the 3 possible > If Liste%(0, I%) = 1 Then > '1 seul octet, c'est immédiat > ChaineMC$ = ChaineMC$ & "913" & Format(Asc(Mid$(Chaine$, > IndexChaine%, 1)), "000") > Else > 'Choisir le commutateur selon qu'on a un multiple de 6 octets ou non > 'Select the switch for perfect multiple of 6 bytes or no > If Liste%(0, I%) Mod 6 = 0 Then > ChaineMC$ = ChaineMC$ & "924" > Else > ChaineMC$ = ChaineMC$ & "901" > End If > J% = 0 > Do While J% < Liste%(0, I%) > Longueur% = Liste%(0, I%) - J% > If Longueur% >= 6 Then > 'prendre des paquets de 6 /Take groups of 6 > Longueur% = 6 > Total = 0 > For K% = 0 To Longueur% - 1 > Total = Total + (Asc(Mid$(Chaine$, IndexChaine% + J% + > K%, 1)) * 256 ^ (Longueur% - 1 - K%)) > Next > ChaineMod$ = Format(Total, "general number") > Dummy$ = "" > Do > Diviseur& = 900 > GoSub Modulo > Dummy$ = Format(Diviseur&, "000") & Dummy$ > ChaineMod$ = ChaineMult$ > If ChaineMult$ = "" Then Exit Do > Loop > ChaineMC$ = ChaineMC$ & Dummy$ > Else > 'S'il reste un paquet de moins de 6 octets / If it remain > a group of less than 6 bytes > For K% = 0 To Longueur% - 1 > ChaineMC$ = ChaineMC$ & Format(Asc(Mid$(Chaine$, > IndexChaine% + J% + K%, 1)), "000") > Next > End If > J% = J% + Longueur% > Loop > End If > Case 902 'Numérique / Numeric > ChaineMC$ = ChaineMC$ & "902" > J% = 0 > Do While J% < Liste%(0, I%) > Longueur% = Liste%(0, I%) - J% > If Longueur% > 44 Then Longueur% = 44 > ChaineMod$ = "1" & Mid$(Chaine$, IndexChaine% + J%, Longueur%) > Dummy$ = "" > Do > Diviseur& = 900 > GoSub Modulo > Dummy$ = Format(Diviseur&, "000") & Dummy$ > ChaineMod$ = ChaineMult$ > If ChaineMult$ = "" Then Exit Do > Loop > ChaineMC$ = ChaineMC$ & Dummy$ > J% = J% + Longueur% > Loop > Debug.Print ChaineMC > End Select > IndexChaine% = IndexChaine% + Liste%(0, I%) > Next > 'ChaineMC$ contient la liste des MC (sur 3 chiffres) représentant les données > 'On s'occupe maintenant du niveau de correction > 'ChaineMC$ contain the MC list (on 3 digits) depicting the datas > 'Now we take care of the correction level > Longueur% = Len(ChaineMC$) / 3 > If sécu% < 0 Then > 'Détermination auto. du niveau de correction en fonction des > recommandations de la norme > 'Fixing auto. the correction level according to the standard > recommendations > If Longueur% < 41 Then > sécu% = 2 > ElseIf Longueur% < 161 Then > sécu% = 3 > ElseIf Longueur% < 321 Then > sécu% = 4 > Else > sécu% = 5 > End If > End If > 'On s'occupe maintenant du nombre de MC par ligne / Now we take care > of the number of CW per row > Longueur% = Longueur% + 1 + (2 ^ (sécu% + 1)) > If nbcol% > 30 Then nbcol% = 30 > If nbcol% < 1 Then > 'Avec une police haute de 3 modules, pour obtenir un code-barre "carré" > 'x = nb. de col. | Largeur en module = 69 + 17x | Hauteur en > module = 3t / x (t étant le nb total de MC) > 'On a donc 69 + 17x = 3t/x <=> 17x²+69x-3t=0 - Le discriminant est > 69²-4*17*-3t = 4761+204t donc x=SQR(discr.)-69/2*17 > ' > 'With a 3 modules high font, for getting a "square" bar code > 'x = nb. of col. | Width by module = 69 + 17x | Height by module = > 3t / x (t is the total number of MCs) > 'Thus we have 69 + 17x = 3t/x <=> 17x²+69x-3t=0 - Discriminant is > 69²-4*17*-3t = 4761+204t thus x=SQR(discr.)-69/2*17 > nbcol% = (Sqr(204# * Longueur% + 4761) - 69) / (34 / 1.3) '1.3 = > coeff. de pondération déterminé au pif après essais / 1.3 = balancing > factor determined at a guess after tests > If nbcol% = 0 Then nbcol% = 1 > End If > 'Si on dépasse 928 MC on essaye de réduire le niveau de correction > 'If we go beyong 928 CWs we try to reduce the correction level > Do While sécu% > 0 > 'Calcul du nombre total de MC en tenant compte du rembourrage pour > compléter les lignes > 'Calculation of the total number of CW with the padding > Longueur% = Len(ChaineMC$) / 3 + 1 + (2 ^ (sécu% + 1)) > Longueur% = (Longueur% \ nbcol% + IIf(Longueur% Mod nbcol% > 0, 1, > 0)) * nbcol% > If Longueur% < 929 Then Exit Do > 'On doit réduire le niveau de sécurité pour tout faire rentrer > 'We must reduce security level > sécu% = sécu% - 1 > CodeErr% = 10 > Loop > If Longueur% > 928 Then CodeErr% = 2: Exit Function > If Longueur% / nbcol% > 90 Then CodeErr% = 3: Exit Function > 'Calcul du rembourrage / Padding calculation > Longueur% = Len(ChaineMC$) / 3 + 1 + (2 ^ (sécu% + 1)) > I% = 0 > If Longueur% \ nbcol% < 3 Then > I% = nbcol% * 3 - Longueur% 'Il faut au moins 3 lignes dans le > code / A bar code must have at least 3 row > Else > If Longueur% Mod nbcol% > 0 Then I% = nbcol% - (Longueur% Mod nbcol%) > End If > 'On ajoute le rembourrage / We add the padding > Do While I% > 0 > ChaineMC$ = ChaineMC$ & "900" > I% = I% - 1 > Loop > 'On ajoute le descripteur de longueur / We add the length descriptor > ChaineMC$ = Format(Len(ChaineMC$) / 3 + 1, "000") & ChaineMC$ > 'On s'occupe maintenant des codes de Reed Solomon / Now we take care > of the Reed Solomon codes > Longueur% = Len(ChaineMC$) / 3 > K% = 2 ^ (sécu% + 1) > ReDim MCcorrection%(K% - 1) > Total = 0 > For I% = 0 To Longueur% - 1 > Total = (Mid$(ChaineMC$, I% * 3 + 1, 3) + MCcorrection%(K% - 1)) Mod 929 > For J% = K% - 1 To 0 Step -1 > If J% = 0 Then > MCcorrection%(J%) = (929 - (Total * Mid$(CoefRS$(sécu%), J% * > 3 + 1, 3)) Mod 929) Mod 929 > Else > MCcorrection%(J%) = (MCcorrection%(J% - 1) + 929 - (Total * > Mid$(CoefRS$(sécu%), J% * 3 + 1, 3)) Mod 929) Mod 929 > End If > Next > Next > For J% = 0 To K% - 1 > If MCcorrection%(J%) <> 0 Then MCcorrection%(J%) = 929 - MCcorrection%(J%) > Next > 'On va ajouter les codes de correction à la chaine / We add theses > codes to the string > For I% = K% - 1 To 0 Step -1 > ChaineMC$ = ChaineMC$ & Format(MCcorrection%(I%), "000") > Next > 'La chaine des MC est terminée > 'Calcul des paramètres pour les MC de cotés gauche et droit > 'The CW string is finished > 'Calculation of parameters for the left and right side CWs > C1% = (Len(ChaineMC$) / 3 / nbcol% - 1) \ 3 > C2% = sécu% * 3 + (Len(ChaineMC$) / 3 / nbcol% - 1) Mod 3 > C3% = nbcol% - 1 > 'On encode chaque ligne / We encode each row > For I% = 0 To Len(ChaineMC$) / 3 / nbcol% - 1 > Dummy$ = Mid$(ChaineMC$, I% * nbcol% * 3 + 1, nbcol% * 3) > K% = (I% \ 3) * 30 > Select Case I% Mod 3 > Case 0 > Dummy$ = Format(K% + C1%, "000") & Dummy$ & Format(K% + C3%, "000") > Case 1 > Dummy$ = Format(K% + C2%, "000") & Dummy$ & Format(K% + C1%, "000") > Case 2 > Dummy$ = Format(K% + C3%, "000") & Dummy$ & Format(K% + C2%, "000") > End Select > pdf417$ = pdf417$ & "+*" 'Commencer par car. de start et > séparateur / Start with a start char. and a separator > For J% = 0 To Len(Dummy$) / 3 - 1 > pdf417$ = pdf417$ & Mid$(CodageMC$(I% Mod 3), Mid$(Dummy$, J% * > 3 + 1, 3) * 3 + 1, 3) & "*" > Next > pdf417$ = pdf417$ & "-" & Chr$(13) & Chr$(10) 'Ajouter car. de > stop et CRLF / Add a stop char. and a CRLF > Next > Exit Function > Regroupe: > 'Regrouper les blocs de même type / Bring together same type blocks > If IndexListe% > 1 Then > I% = 1 > Do While I% < IndexListe% > If Liste%(1, I% - 1) = Liste%(1, I%) Then > 'Regroupement / Bringing together > Liste%(0, I% - 1) = Liste%(0, I% - 1) + Liste%(0, I%) > J% = I% + 1 > 'Réduction de la liste / Decrease the list > Do While J% < IndexListe% > Liste%(0, J% - 1) = Liste%(0, J%) > Liste%(1, J% - 1) = Liste%(1, J%) > J% = J% + 1 > Loop > IndexListe% = IndexListe% - 1 > I% = I% - 1 > End If > I% = I% + 1 > Loop > End If > Return > QuelMode: > CodeASCII% = Asc(Mid$(Chaine$, IndexChaine%, 1)) > Select Case CodeASCII% > Case 48 To 57 > Mode% = 902 > Case 9, 10, 13, 32 To 126 > Mode% = 900 > Case Else > Mode% = 901 > End Select > Return > Modulo: > 'ChaineMod$ représente un très grand nombre sur plus de 9 chiffres > 'Diviseur& est le diviseur, contient le résultat au retour > 'ChaineMult$ contient au retour le résultat de la division entière > ' > 'ChaineMod$ depict a very large number having more than 9 digits > 'Diviseur& is the divisor, contain the result after return > 'ChaineMult$ contain after return the result of the integer division > ChaineMult$ = "" > Nombre& = 0 > Do While ChaineMod$ <> "" > Nombre& = Nombre& * 10 + Left$(ChaineMod$, 1) 'Abaisse un chiffre > / Put down a digit > ChaineMod$ = Mid$(ChaineMod$, 2) > If Nombre& < Diviseur& Then > If ChaineMult$ <> "" Then ChaineMult$ = ChaineMult$ & "0" > Else > ChaineMult$ = ChaineMult$ & Nombre& \ Diviseur& > End If > Nombre& = Nombre& Mod Diviseur& 'Récupère le reste / get the remainder > Loop > Diviseur& = Nombre& > Return > End Function > > > 2010/2/5 Viktor Szakáts <harbour...@syenar.hu>: >> Thank you. Forgot to mention but I need something in .prg code. >> >> Brgds, >> Viktor >> >> On 2010 Feb 5, at 12:42, Mindaugas Kavaliauskas wrote: >> >>> Hi, >>> >>> >>>> Does anyone have source code to generate PDF417 barcodes? >>>> (using .ttf file or graphical shapes if possible) >>> >>> http://sourceforge.net/projects/pdf417lib/ >>> >>> >>> Regards, >>> Mindaugas >>> _______________________________________________ >>> Harbour mailing list (attachment size limit: 40KB) >>> Harbour@harbour-project.org >>> http://lists.harbour-project.org/mailman/listinfo/harbour >> >> _______________________________________________ >> Harbour mailing list (attachment size limit: 40KB) >> Harbour@harbour-project.org >> http://lists.harbour-project.org/mailman/listinfo/harbour >> > > > > -- > Massimo Belgrano > > Iscritto all'albo dei CTU presso il Tribunale di Novara per materia > Informatica > Delta Informatica S.r.l. (http://www.deltain.it/) (+39 0321 455962) > Analisi e sviluppo software per Lan e Web - Consulenza informatica - > Formazione > _______________________________________________ > Harbour mailing list (attachment size limit: 40KB) > Harbour@harbour-project.org > http://lists.harbour-project.org/mailman/listinfo/harbour _______________________________________________ Harbour mailing list (attachment size limit: 40KB) Harbour@harbour-project.org http://lists.harbour-project.org/mailman/listinfo/harbour