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

Reply via email to