Here is a set of functions i began to create in 2005, to replace integraly the same functions
of Pagescript than i used when i worked for mister DOS. These functions work very nice,
but if you have any suggest to me, don't private you !
The "out on .pdf" is not implemented today, but you can already use this in waiting.
- Code: Select all Expand view
***********************************************************************************
****** ICImprim.PRG ***************************************************************
***********************************************************************************
****** Creation le 04/01/2005
****** Derniere modification le 12/10/2013 à 21:30:08
****** Auteur : Badara THIAM
****** Description : fonctions remplaçant la plupart des fonctions équivalentes de PageScript
****** Aujourd'hui ces fonctions ne gèrent pas l'impression directe dans un fichier .pdf mais Badara THIAM
****** souhaite inclure le code nécessaire à chaque fonction dans un proche avenir, si les fonctions
****** disponibles sous (x)Harbour le permettent
***********************************************************************************
#include "fivewin.ch"
#IFNDEF __XPP__
#define HKEY_CLASSES_ROOT 2147483648 // 0x80000000
#define HKEY_CURRENT_USER 2147483649 // 0x80000001
#define HKEY_LOCAL_MACHINE 2147483650 // 0x80000002
#define HKEY_USERS 2147483651 // 0x80000003
#define HKEY_PERFORMANCE_DATA 2147483652 // 0x80000004
#define HKEY_CURRENT_CONFIG 2147483653 // 0x80000005
#define HKEY_DYN_DATA 2147483654 // 0x80000006
#ELSE
#define HKEY_CLASSES_ROOT 1
#define HKEY_CURRENT_USER 2
#define HKEY_LOCAL_MACHINE 3
#define HKEY_USERS 4
#define HKEY_PERFORMANCE_DATA 5
#define HKEY_CURRENT_CONFIG 6
#define HKEY_DYN_DATA 7
#ENDIF
// Registry Specific Access Rights.
#define KEY_QUERY_VALUE 1 // 0x0001
#define KEY_SET_VALUE 2 // 0x0002
#define KEY_CREATE_SUB_KEY 4 // 0x0004
#define KEY_ENUMERATE_SUB_KEYS 8 // 0x0008
#define KEY_NOTIFY 16 // 0x0010
#define KEY_CREATE_LINK 32 // 0x0020
/* device capabilities indices */
#define DC_FIELDS 1
#define DC_PAPERS 2
#define DC_PAPERSIZE 3
#define DC_MINEXTENT 4
#define DC_MAXEXTENT 5
#define DC_BINS 6
#define DC_DUPLEX 7
#define DC_SIZE 8
#define DC_EXTRA 9
#define DC_VERSION 10
#define DC_DRIVER 11
#define DC_BINNAMES 12
#define DC_ENUMRESOLUTIONS 13
#define DC_FILEDEPENDENCIES 14
#define DC_TRUETYPE 15
#define DC_PAPERNAMES 16
#define DC_ORIENTATION 17
#define DC_COPIES 18
#define SRCCOPY 13369376 // 0x00CC0020L
#define SRCPAINT 15597702 // 0x00EE0086L
STATIC oPrn
STATIC oFont
STATIC nPage
STATIC nCOPIE
STATIC lASSEMBLER
STATIC lINVERSER
STATIC HDCFW
*******************
FUNCTION PSREFRESHP()
*******************
* OK
RETURN NIL
***************
FUNCTION PSINIT()
***************
RETURN 0
***********************
FUNCTION PSSETTIMESLICE()
***********************
* OK
RETURN NIL
*******************
FUNCTION PSSETDECIM()
*******************
* OK
RETURN NIL
*******************
FUNCTION PSGETFONTS(NIMP)
*******************
* Liste des fontes disponibles pour l'imprimante Nø NIMP
RETURN {}
*******************
FUNCTION PSGETPRINTERS()
*******************
* retourne la liste des imprimantes disponibles sous windows depuis le poste de travail courant
* Recherche dans le fichier WIN.INI si rien dans le registre de Windows
LOCAL TIMP := {}
LOCAL REPWIN := GETREPWIN()
LOCAL NOTES
LOCAL NOTLIG
IF !EMPTY(REPWIN)
TIMP := WinGetPrn()
IF LEN(TIMP) = 0 .AND. ( " " + cWinVersion() + " " $ " 95 98 " )
NOTES := FileToMemo(REPWIN + "\WIN.INI")
IF !EMPTY(NOTES)
NOTES := ANSIASCI(NOTES)
IF "[DEVICES]" $ MAJ(NOTES)
NOTES := SUBSTR(NOTES, AT("[DEVICES]", MAJ(NOTES)) )
IF CRLF $ NOTES
NOTES := SUBSTR(NOTES, AT(CRLF, NOTES) + LEN(CRLF))
DO WHILE !EMPTY(NOTES)
IF CRLF $ NOTES
NOTLIG := LEFT(NOTES, AT(CRLF, NOTES)-1)
NOTES := SUBSTR(NOTES, AT(CRLF, NOTES) + LEN(CRLF))
ELSE
NOTLIG := NOTES
NOTES := ""
ENDIF
IF LEFT(LTRIM(NOTLIG), 1) == "["
EXIT
ELSEIF !EMPTY(NOTLIG)
AADD(TIMP, LEFT(NOTLIG, AT("=",NOTLIG) - 1) )
ENDIF
ENDDO
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
RETURN ACLONE( TIMP )
******************
FUNCTION WinGetPrn( lOrigine )
******************
* Recherche les imprimantes installées sous windows dans le registre de Windows
* Auteur Badara Thiam
LOCAL lSetExact := SET( _SET_EXACT, .T. )
LOCAL TIMP := {}
LOCAL cValue
LOCAL n1
LOCAL n2
LOCAL nok
LOCAL nLen
LOCAL cSubkeys
LOCAL nHKey := HKEY_LOCAL_MACHINE
LOCAL TSERVEURS := {}
LOCAL X
LOCAL oReg
LOCAL oRegSubK
* Recherche des imprimantes disponibles depuis le poste courant
cSubKeys := "System\CurrentControlSet\Control\Print\Printers"
oReg := TReg32():New( nHKey, cSubKeys, , KEY_ENUMERATE_SUB_KEYS )
IF oReg:nError = 0
n1 := 0
DO WHILE .T.
cValue := ""
n2 := RegEnumKey( oReg:nHandle, n1, @cvalue )
SysRefresh()
IF n2 = 0
IF ASCAN(TIMP, STRTRAN(cValue, "," , "\")) = 0
SysRefresh()
AADD(TIMP, STRTRAN(cValue, "," , "\"))
ENDIF
ELSE
EXIT
ENDIF
n1 ++
ENDDO
SysRefresh()
oReg:Close()
ENDIF
* Recherche des imprimantes réseau non répertoriées dans la clé précédente (ci-dessus)
* Ajouté le 20/10/2006
TSERVEURS := WinGetSP()
* Recherche des imprimantes non répertoriées dans les clés prédédentes (cas avec Windows 7 et peut-être suivants)
* Ajouté le 14/04/2013
cSubKeys := "Printers\Connections"
nHKey := HKEY_CURRENT_USER
oReg := TReg32():New( nHKey, cSubKeys, , KEY_ENUMERATE_SUB_KEYS )
IF oReg:nError = 0
n1 := 0
DO WHILE .T.
cValue := ""
n2 := RegEnumKey( oReg:nHandle, n1, @cvalue )
SysRefresh()
IF n2 = 0
IF ASCAN(TIMP, STRTRAN(cValue, "," , "\")) = 0
SysRefresh()
AADD(TIMP, STRTRAN(cValue, "," , "\"))
ENDIF
ELSE
EXIT
ENDIF
n1 ++
ENDDO
SysRefresh()
oReg:Close()
ENDIF
nHKey := HKEY_LOCAL_MACHINE
IF !EMPTY(TSERVEURS)
FOR X := 1 TO LEN(TSERVEURS)
cSubKeys := TSERVEURS[X][2] + "\" + TSERVEURS[X][1] + "\Printers"
oRegSubK := TReg32():New( TSERVEURS[X][3], cSubKeys, , KEY_ENUMERATE_SUB_KEYS )
IF oRegSubK:nError = 0
n1 := 0
DO WHILE .T.
cValue := ""
n2 := RegEnumKey( oRegSubK:nHandle, n1, @cvalue )
SysRefresh()
IF n2 = 0
* Pour vista : le nom d'imprimante (sous précédents os) est le port, codé avec "{" et "}"
IF EMPTY( lOrigine ) .AND. ( "{" $ cValue )
oReg := TReg32():New( TSERVEURS[X][3], TSERVEURS[X][2] + "\" + TSERVEURS[X][1] + "\Printers" ;
+ "\" + cValue + "\PrinterDriverData", , KEY_QUERY_VALUE )
IF oReg:nError = 0
cValue := oReg:Get("Model", "")
ENDIF
oReg:Close()
ENDIF
IF ASCAN(TIMP, STRTRAN(cValue, "," , "\")) = 0
IF "," $ cValue
AADD(TIMP, STRTRAN(cValue, "," , "\"))
ELSE
AADD(TIMP, "\\" + TSERVEURS[X][1] + "\" + cValue)
ENDIF
ENDIF
SysRefresh()
ELSE
EXIT
ENDIF
n1 ++
ENDDO
oRegSubK:Close()
ENDIF
SysRefresh()
NEXT X
ENDIF
SET( _SET_EXACT, lSetExact )
RETURN ACLONE(TIMP)
*****************
FUNCTION WinGetSP()
*****************
* Renvoie un tableau dont chaque élément est un tableau contenant
* 1 : les noms des serveurs d'impression disponibles pour le poste courant
* 2 : la sous-clé dans le registre Windows où est localisée l'information concernant le serveur
* 3 : clé dans le registre Windows où est localisée l'information concernant le serveur
* Auteur Badara Thiam
LOCAL lSetExact := SET( _SET_EXACT, .T. )
LOCAL cValue
LOCAL n1
LOCAL n2
LOCAL cSubkeys
LOCAL nHKey
LOCAL TSERVEURS := {}
LOCAL nSubK := 0
LOCAL oReg
DO WHILE .T.
nSubK ++
IF nSubK = 1
nHKey := HKEY_LOCAL_MACHINE
cSubKeys := "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers"
ELSEIF nSubK = 2
* Sous Vista version premium familiale et Windows 7
nHKey := HKEY_LOCAL_MACHINE
cSubKeys := "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\Client Side Rendering Print Provider\Servers"
ELSE
EXIT
ENDIF
oReg := TReg32():New( nHKey, cSubKeys, , KEY_ENUMERATE_SUB_KEYS )
IF oReg:nError = 0
* Recherche des serveurs accessibles
n1 := 0
DO WHILE .T.
cValue := ""
n2 := RegEnumKey( oReg:nHandle, n1, @cvalue )
SysRefresh()
IF n2 = 0
IF ASCAN(TSERVEURS, { ¦qelem¦ qelem[1] = cValue } ) = 0
AADD(TSERVEURS, ACLONE( { cValue, cSubKeys, nHKey } ) )
ENDIF
ELSE
EXIT
ENDIF
SysRefresh()
n1 ++
ENDDO
oReg:Close()
ENDIF
ENDDO
SET( _SET_EXACT, lSetExact )
RETURN ACLONE(TSERVEURS)
*******************
FUNCTION WinGetSerP()
*******************
* Renvoie dans un tableau les noms des serveurs d'impression disponibles pour le poste courant
* Auteur Badara Thiam
LOCAL N
LOCAL TSERVEURS := WinGetSP()
LOCAL aServeurs := {}
FOR N := 1 TO LEN(TSERVEURS)
AADD( aServeurs, TSERVEURS[N][1] )
NEXT N
RETURN ACLONE(aServeurs)
*******************
FUNCTION WinGetPrnD(cNomDriver)
*******************
* Recherche le driver d'une imprimante installée sous windows
* dans le registre de Windows (remplace le WIN.INI qui est obsolète sous Windows 2000 et suivants)
* Auteur Badara THIAM
LOCAL lSetExact := SET( _SET_EXACT, .T. )
LOCAL cValue
LOCAL n1
LOCAL n2
LOCAL nok
LOCAL nLen
LOCAL cSubkeys
LOCAL cSubkeys2
LOCAL cSubkeys3
LOCAL X, X2
LOCAL XENV
LOCAL TENV := {}
LOCAL TVERDRIVER := {}
LOCAL oReg
LOCAL nHKey
LOCAL cDriver := ""
X := 0
DO WHILE EMPTY(cDriver)
X ++
TENV := {}
TVERDRIVER := {}
cDriver := ""
IF X = 1
cSubKeys := "System\CurrentControlSet\Control\Print\Environments"
nHKey := HKEY_LOCAL_MACHINE
ELSEIF X = 2
cSubKeys := "System\ControlSet001\Control\Print\Environments"
nHKey := HKEY_LOCAL_MACHINE
ELSEIF X = 3
cSubKeys := "System\ControlSet002\Control\Print\Environments"
nHKey := HKEY_LOCAL_MACHINE
ELSE
EXIT
ENDIF
oReg := TReg32():New(nHKey, cSubKeys, , KEY_ENUMERATE_SUB_KEYS )
IF oReg:nError = 0
* Stocke tous les sous chemins de ..\Environments
* dans le tableau TENV, pour analyse le contenu de chaque "environment"
SysRefresh()
n1 := 0
DO WHILE .T.
cValue := ""
n2 := RegEnumKey( oReg:nHandle, n1, @cvalue )
IF n2 = 0
IF ASCAN(TENV, STRTRAN(cValue, "," , "\")) = 0
AADD(TENV, STRTRAN(cValue, "," , "\"))
ENDIF
ELSE
EXIT
ENDIF
n1 ++
SysRefresh()
ENDDO
oReg:Close()
SysRefresh()
ENDIF
FOR XENV := 1 TO LEN(TENV)
cSubKeys2 := cSubKeys + "\" + TENV[XENV] + "\Drivers"
cSubKeys3 := cSubKeys2 + "\" + cNomDriver
oReg := TReg32():New(nHKey, cSubKeys3, , KEY_QUERY_VALUE)
IF oReg:nError = 0
* Si le nom de l'imprimante est présent dans le chemin ..\Drivers
cDriver := oReg:Get("Driver", "")
oReg:Close()
oReg := NIL
IF !EMPTY(cDriver)
cDriver := IIF("." $ cDriver, LEFT(cDriver, AT(".", cDriver) - 1), cDriver)
EXIT
ENDIF
ELSE
oReg:Close()
oReg := NIL
oReg := TReg32():New(nHKey, cSubKeys2, , KEY_ENUMERATE_SUB_KEYS )
IF oReg:nError = 0
n1 := 0
TVERDRIVER := {}
DO WHILE .T.
cValue := ""
n2 := RegEnumKey( oReg:nHandle, n1, @cvalue )
IF n2 = 0
IF ASCAN(TVERDRIVER, STRTRAN(cValue, "," , "\")) = 0
AADD(TVERDRIVER, STRTRAN(cValue, "," , "\"))
ENDIF
ELSE
EXIT
ENDIF
SysRefresh()
n1 ++
ENDDO
oReg:Close()
SysRefresh()
FOR X2 := 1 TO LEN(TVERDRIVER)
cSubKeys3 := cSubKeys2 + "\" + TVERDRIVER[X2] + "\" + cNomDriver
oReg := TReg32():New(nHKey, cSubKeys3, , KEY_QUERY_VALUE)
IF oReg:nError = 0
cDriver := oReg:Get("Driver", "")
SysRefresh()
oReg:Close()
oReg := NIL
IF !EMPTY(cDriver)
cDriver := IIF("." $ cDriver, LEFT(cDriver, AT(".", cDriver) - 1), cDriver)
EXIT
ENDIF
ELSE
oReg:Close()
oReg := NIL
ENDIF
SysRefresh()
NEXT X2
IF !EMPTY(cDriver)
EXIT
ENDIF
ENDIF
ENDIF
SysRefresh()
NEXT XENV
ENDDO
SysRefresh()
SET( _SET_EXACT, lSetExact )
RETURN cDriver
*******************
FUNCTION WinGetPrnP(cNomImpr)
*******************
* Renvoie le (nom du fichier) Driver et le Port de l'imprimante dont le nom est le contenu de cNomImpr.
* Le Driver et le Port sont renvoyés dans une chaine, séparés par une virgule.
* Auteur Badara THIAM
LOCAL lSetExact := SET( _SET_EXACT, .T. )
LOCAL cDriver := ""
LOCAL cNomDriver := ""
LOCAL cPort := ""
LOCAL oReg
LOCAL X
LOCAL Y
LOCAL TIMP := WinGetPrn()
LOCAL TImpOrig := WinGetPrn(.T.)
LOCAL TSERVEURS := {}
* Recherche l'imprimante Windows ayant le même nom,
* en convertissant en minuscule et en supprimant les espaces
FOR X := 1 TO LEN(TIMP)
IF MEMEIMPRIM(@cNomImpr, TIMP[X])
* Si c'est la même imprimante
EXIT
ENDIF
NEXT X
IF X <= LEN(TIMP)
IF "\" $ TIMP[X] .AND. TIMP[X] != TImpOrig[X]
* Si imprimante réseau
TSERVEURS := WinGetSP()
FOR Y := 1 TO LEN(TSERVEURS)
oReg := TReg32():New( TSERVEURS[Y][3], TSERVEURS[Y][2] ;
+ "\" + TSERVEURS[Y][1] + "\Printers\" + SUBSTR(TImpOrig[X], RAT("\",TImpOrig[X]) + 1) ;
+ "\DsSpooler", , KEY_QUERY_VALUE )
IF oReg:nError = 0
EXIT
ENDIF
oReg:Close()
oReg := NIL
NEXT Y
IF oReg != NIL
IF oReg:nError = 0
cPort := oReg:Get("portName", "")
cNomDriver := oReg:Get("driverName", "")
ENDIF
oReg:Close()
oReg := NIL
ENDIF
ELSE
oReg := TReg32():New(HKEY_LOCAL_MACHINE,;
"System\CurrentControlSet\Control\Print\Printers\" + STRTRAN(TIMP[X],"\",","), , KEY_QUERY_VALUE)
IF oReg:nError <> 0
* Cherche si cette imprimante non répertoriée est en réseau (10/2006)
oReg:Close()
oReg := NIL
TSERVEURS := WinGetSP()
FOR Y := 1 TO LEN(TSERVEURS)
oReg := TReg32():New( TSERVEURS[Y][3], TSERVEURS[Y][2] ;
+ "\" + TSERVEURS[Y][1] + "\Printers\" + STRTRAN(TIMP[X],"\",","), , KEY_QUERY_VALUE)
IF oReg:nError = 0
EXIT
ELSEIF "\" $ TIMP[X]
* Si "\" est présent dans le nom d'imprimante, c'est "peut-être" la fonction WinGetPrn()
* qui a inséré le nom de serveur dans le nom d'imprimante. Pour le vérifier,
* recherche également le nom de l'imprimante sans le nom de serveur
oReg:Close()
oReg := NIL
oReg := TReg32():New( TSERVEURS[Y][3], TSERVEURS[Y][2] ;
+ "\" + TSERVEURS[Y][1] + "\Printers\" + SUBSTR(TIMP[X], RAT("\",TIMP[X]) + 1 ), , KEY_QUERY_VALUE )
IF oReg:nError = 0
EXIT
ENDIF
ENDIF
oReg:Close()
oReg := NIL
NEXT Y
ENDIF
IF oReg != NIL
IF oReg:nError = 0
cPort := oReg:Get("Port", "")
cNomDriver := oReg:Get("Printer Driver", "")
ENDIF
oReg:Close()
oReg := NIL
ENDIF
ENDIF
IF cNomDriver != ""
cDriver := WinGetPrnD( STRTRAN(cNomDriver, CHR(0), "") )
ENDIF
ENDIF
SET( _SET_EXACT, lSetExact )
RETURN cDriver + "," + cPort
******************
FUNCTION WinDefPrn()
******************
* Dernière modification le 17/11/2006
* Retourne le nom de l'imprimante par défaut en allant le chercher dans le registre Windows
* (regedit.exe)
LOCAL cDefPrn := ""
* Adresse dans le registre pour Windows 2000 et suivants
LOCAL oReg := TReg32():New(HKEY_CURRENT_USER, "Software\Microsoft\Windows NT\CurrentVersion\Windows", , KEY_QUERY_VALUE)
IF oReg:nError = 0
cDefPrn := oReg:Get("Device", "")
IF "," $ cDefPrn
* Suppression du Pilote et du Port, non requis ici
cDefPrn := LEFT(cDefPrn, AT(",",cDefPrn) -1)
ENDIF
ELSE
* Alternative pour Windows 9x et Millennium
oReg:Close()
oReg := NIL
oReg := TReg32():New(HKEY_CURRENT_CONFIG, "System\CurrentControlSet\Control\Print\Printers", , KEY_QUERY_VALUE)
IF oReg:nError = 0
cDefPrn := oReg:Get("Default", "")
ENDIF
ENDIF
oReg:Close()
oReg := NIL
RETURN cDefPrn
*******************
FUNCTION PSGETDEFPR()
*******************
* Imprimante par défaut
* Retourne le numéro d'élément, dans le tableau des imprimantes retourné par PSGETPRINTERS()
LOCAL REPWIN := GETREPWIN()
LOCAL NOTES := ""
LOCAL nRet := 0
IF !EMPTY(REPWIN)
* Cherche d'abord dans le registre Windows
NOTES := WINDEFPRN()
IF EMPTY(NOTES) .AND. ( " " + cWinVersion() + " " $ " 95 98 " )
* Si introuvable dans le registre windows et version de windows compatible avec WIN.INI
NOTES := FileToMemo(REPWIN + "\WIN.INI")
IF !EMPTY(NOTES)
NOTES := ANSIASCI(NOTES)
IF "DEVICE=" $ MAJ(NOTES)
NOTES := SUBSTR(NOTES, AT("DEVICE=", MAJ(NOTES)) + 7 )
IF CRLF $ NOTES
NOTES := LEFT(NOTES, AT(CRLF, NOTES) - 1)
ENDIF
IF "," $ NOTES
NOTES := TRIM(LEFT(NOTES, AT(",",NOTES) - 1))
ENDIF
ELSE
NOTES := ""
ENDIF
ENDIF
ENDIF
IF !EMPTY(NOTES)
nRet := ASCAN(PSGETPRINTERS(), NOTES )
ENDIF
ENDIF
RETURN nRet
******************
FUNCTION WinDevMode(cNomImpr)
******************
* Retourne le contenu DevMode en allant le chercher dans le registre Windows
* (regedit.exe)
* Inutilisée pour le moment (conversion en données compréhensibles à faire
* pour le contenu récupéré )
LOCAL cDevMode := ""
LOCAL oReg := TReg32():New(HKEY_LOCAL_MACHINE,;
"System\CurrentControlSet\Control\Print\Printers\" + STRTRAN(cNomImpr, "\", ","), , KEY_QUERY_VALUE)
IF oReg:nError = 0
cDevMode := oReg:Get("Default DevMode", "")
ENDIF
oReg:Close()
oReg := NIL
RETURN cDevMode
******************
FUNCTION PSTEXTOUT(nRow, nCol, cText, cPicture, nAligne, cFont, nStyle, nPoint, ;
nFColor, nBColor, nAngle )
******************
STATIC ancnPoint
STATIC ancnOrient
STATIC cTexteAff
STATIC nRetour
LOCAL lFonteSupp := .F.
LOCAL oFonte
LOCAL nDixiemeAngle := IIF(nAngle = NIL, 0, nAngle * 10)
* Si cFont = NIL, la dernière fonte activée avant l'appel de cette fonction
* est utilisée par défaut
IF !EMPTY(cFont)
oFonte := TFont():New( cFont, , nPoint, ,, nDixiemeAngle, nDixiemeAngle,,,,,,,,, oPrn, )
lFonteSupp := .T.
ELSEIF (nPoint != NIL .OR. !EMPTY(nDixiemeAngle)) .AND. oFont != NIL
ancnOrient := oFont:nOrientation
ancnPoint := oFont:nHeight
PSSetFont2( @nDixiemeAngle, @nPoint)
ENDIF
IF oFonte = NIL
oFonte := oFont
ENDIF
IF cPicture = NIL
cTexteAff := ASCIANSI(cText)
ELSE
cTexteAff := ASCIANSI(TRANSFORM(cText, cPicture))
ENDIF
IF nRow = NIL
nRetour := GetTextWidth( oPrn:hDC, cTexteAff, oFonte:hFont )
ELSE
oprn:Say( nRow, nCol, cTexteAff, oFonte, , nFColor, 1, nAligne )
nRetour := NIL
ENDIF
IF oFonte != NIL .AND. lFonteSupp
oFonte:End()
oFonte := NIL
ELSEIF (nPoint != NIL .OR. !EMPTY(nDixiemeAngle)) .AND. oFont != NIL
PSSetFont2( @ancnOrient, @ancnPoint)
ENDIF
RETURN nRetour
******************
FUNCTION PSSetFont(cFont, nStyle, nPoint, nFColor, nBColor)
******************
* Fonction retournant un tableau contenant les valeurs précédentes :
* { <cOldFont>, <nOldStyle>, <nOldPoint>, <nOldFColor>, <nOldBColor> }
LOCAL ANCIENNEF[5]
* Styles :
*APS_PLAIN 0 Plain
*APS_BOLD 1 Bold
*APS_ITALIC 2 Italic
*APS_BOLDITALIC 3 Bold + Italic
*APS_UNDERLINE 4 UnderLine
*APS_STRIKEOUT 8 StrikeOut
* Tableau de description des fontes avec Fivewin, pour CreateFont()
* LF_HEIGHT 1
* LF_WIDTH 2
* LF_ESCAPEMENT 3
* LF_ORIENTATION 4
* LF_WEIGHT 5
* LF_ITALIC 6
* LF_UNDERLINE 7
* LF_STRIKEOUT 8
* LF_CHARSET 9
* LF_OUTPRECISION 10
* LF_CLIPPRECISION 11
* LF_QUALITY 12
* LF_PITCHANDFAMILY 13
* LF_FACENAME 14
ANCIENNEF := ANCFONTE(0)
IF oFont != NIL
* Récupère le nom et la hauteur de la dernière fonte réellement activée
ANCIENNEF[1] := oFont:cFaceName
ANCIENNEF[3] := oFont:nHeight
ENDIF
IF cFont != NIL
ANCFONTE(1, cFont)
ENDIF
IF nStyle != NIL
ANCFONTE(2, nStyle)
ENDIF
IF nPoint != NIL
ANCFONTE(3, nPoint)
ENDIF
IF nFColor != NIL
ANCFONTE(4, nFColor)
ENDIF
IF nBColor != NIL
ANCFONTE(5, nBColor)
ENDIF
PSSetFont2()
RETURN ACLONE(ANCIENNEF)
*******************
FUNCTION PSSetFont2(nOriente, nPointHaut)
*******************
STATIC ANCPOINTH
*oFont := TFont():New( cFaceName, nWidth, nHeight, lFromUser, lBold,;
* nEscapement, nOrientation, nWeight, lItalic, lUnderline,;
* lStrikeOut, nCharSet, nOutPrecision, nClipPrecision,;
* nQuality, oDevice, nPitchFamily ) CLASS TFont
IF oFont != NIL
oFont:End()
oFont := NIL
ENDIF
IF nPointHaut != NIL
ANCPOINTH := ANCFONTE(3)
ANCFONTE(3, nPointHaut)
ENDIF
IF EMPTY(ANCFONTE(2))
* Normal
oFont := TFont():New( ANCFONTE(1), , ANCFONTE(3), , , nOriente, nOriente, , , ,,,,,, @oPrn, )
ELSE
oFont := TFont():New( ANCFONTE(1), , ANCFONTE(3), ,;
ANCFONTE(2) % 2 = 1, nOriente, nOriente, , ANCFONTE(2) % 4 >= 2,;
ANCFONTE(2) % 8 >= 4, ANCFONTE(2) >= 8,,,,, @oPrn, )
ENDIF
IF oFont != NIL .AND. oPrn != NIL
oPrn:SetFont( oFont )
ENDIF
IF ANCPOINTH != NIL
ANCFONTE(3, ANCPOINTH)
ANCPOINTH := NIL
ENDIF
RETURN NIL
***********************
FUNCTION IMPFonteHauteur()
***********************
* Retourne la hauteur d'une fonte en pixels, ou zéro si aucune fonte en cours pour impression
IF !EMPTY(oFont)
RETURN oFont:nHeight
ENDIF
RETURN 0
*****************
FUNCTION ANCFONTE(nCas, nVal)
*****************
STATIC ANCFONTE := {"",,,,}
IF nVal != NIL
ANCFONTE[nCas] := nVal
RETURN NIL
ELSEIF nCas = NIL
ANCFONTE := ARRAY(LEN(ANCFONTE))
RETURN NIL
ELSEIF nCas = 0
RETURN ACLONE(ANCFONTE)
ENDIF
RETURN ANCFONTE[nCas]
****************
FUNCTION PSFRAME(nR1, nC1, nR2, nC2, EPAISSEUR, nBColor, nFColor, nPattern)
****************
STATIC oBrush
STATIC oPen
LOCAL nEpaisseur := IIF(EPAISSEUR = NIL, PSSETBORDER()[1], EPAISSEUR)
IF nFColor != NIL .AND. nEpaisseur > 0
oPen := TPen():New(PS_SOLID, PointToPix(MAX( oPrn:nLogPixelX(), oPrn:nLogPixelY()) , nEpaisseur ), ;
IIF(nFColor = NIL, PSSETBORDER()[2], nFColor) )
oPrn:Box( nR1, nC1, nR2, nC2, oPen )
oPen:End()
ENDIF
IF nBColor != NIL
oBrush := TBrush():New( , nBColor, , )
IF nFColor != NIL .AND. nEpaisseur > 0
oPrn:FillRect( { nR1 + nEpaisseur, nC1 + nEpaisseur, nR2 - nEpaisseur, nC2 - nEpaisseur }, oBrush )
ELSE
oPrn:FillRect( { nR1, nC1, nR2, nC2 }, oBrush )
ENDIF
oBrush:End()
ENDIF
RETURN NIL
*****************
FUNCTION PSBITMAP(nR1, nC1, nR2, nC2, cBitmapFile, nTransColor, lDeleteFile, lKeepRatio)
*****************
* Imprime un fichier .BMP
oPrn:SayBitmap( nR1, nC1, cBitmapFile, nC2 - nC1 + 1, nR2 - nR1 + 1, , nTranscolor )
RETURN NIL
**********************
FUNCTION PSSETPAGESIZE(nPageType)
**********************
STATIC nPageT
IF nPageType != NIL
nPageT := nPageType
RETURN NIL
ENDIF
RETURN nPageT
******************
FUNCTION PSGETCAPS(NPRINTER, nOriente)
******************
* Les "#define" ci-dessous sont dans WINDOWS.CH
#define HORZSIZE 4
#define VERTSIZE 6
#define HORZRES 8
#define VERTRES 10
#define BITSPIXEL 12
#define LOGPIXELSX 88
#define LOGPIXELSY 90
*APC_PAPERWIDTH 1 Paper width
*APC_PAPERHEIGHT 2 Paper height
*APC_AREAWIDTH 3 Printable area width
*APC_AREAHEIGHT 4 Printable area height
*APC_TOPMARGIN 5 Top margin
*APC_LEFTMARGIN 6 Left margin
*APC_HPIXELS 7 Number of horizontal pixels per inch
*APC_VPIXELS 8 Number of vertical pixels per inch
*APC_BITSPIXEL 9 Number of bits per pixels. 1 bit = B & W and bits > 1 = color.
STATIC TCAPS[9]
LOCAL oPrint
LOCAL aPixCoord
IF !EMPTY(NPRINTER)
SysRefresh()
IF oPrn = NIL
TCAPS := ARRAY(LEN(TCAPS))
oPrint := TPrinter():New( "", .F., .F., PSGETPRINTERS()[NPRINTER], .T., .F. )
InitPrnDim(@oPrint, @nOriente)
TCAPS[3] := GetDeviceCaps( oPrint:hDC, HORZRES )
TCAPS[4] := GetDeviceCaps( oPrint:hDC, VERTRES )
IF nOriente = 0
TCAPS[5] := oPrint:nYOffset
TCAPS[6] := oPrint:nXOffset
TCAPS[7] := GetDeviceCaps( oPrint:hDC, LOGPIXELSY )
TCAPS[8] := GetDeviceCaps( oPrint:hDC, LOGPIXELSX )
ELSE
TCAPS[5] := oPrint:nXOffset
TCAPS[6] := oPrint:nYOffset
TCAPS[7] := GetDeviceCaps( oPrint:hDC, LOGPIXELSX )
TCAPS[8] := GetDeviceCaps( oPrint:hDC, LOGPIXELSY )
ENDIF
IF TCAPS[5] = NIL
TCAPS[5] := 0
ENDIF
IF TCAPS[6] = NIL
TCAPS[6] := 0
ENDIF
SysRefresh()
aPixCoord := oPrint:GetPhySize()
SysRefresh()
TCAPS[1] := INT(( aPixCoord[1] / 25.4 ) * TCAPS[7])
TCAPS[2] := INT(( aPixCoord[2] / 25.4 ) * TCAPS[8])
TCAPS[9] := GetDeviceCaps( oPrint:hDC, BITSPIXEL )
PrintEnd( @OPrint, .T. )
ENDIF
ELSEIF oPrn = NIL
RETURN ARRAY(LEN(TCAPS))
ENDIF
RETURN ACLONE( TCAPS )
*******************
FUNCTION InitPrnDim( oPrint, nOriente )
*******************
* Format du papier
PSSETPAGESIZE( PSFORMPAPI("D") )
PrnSetPage( PSSETPAGESIZE() )
IF nOriente = 0
oPrint:SetPortrait()
ELSE
oPrint:SetLandscape()
ENDIF
RETURN NIL
*******************
FUNCTION PSBEGINDOC(NIMP, QTITRE, nOriente, nCopies, lASSEMB, lINVERS)
*******************
ANCFONTE()
* Avec ou Sans Prévisualisation selon la valeur logique contenue dans PSSetDevice()
oPrn := TPrinter():New( ASCIANSI( PROPRE(QTITRE) ), .F., .T., PSGETPRINTERS()[NIMP], .T., , PSSetDevice() = 2 )
InitPrnDim( @oPrn, @nOriente )
* Nombre d'exemplaires
nCOPIE := nCopies
* permet d'Assembler chaque exemplaire si multi-copie
lASSEMBLER := lASSEMB
* pour inverser l'impression, de la dernière à la première page
lINVERSER := lINVERS
oPrn:SetCopies( nCopies )
PageBegin( @oPrn )
nPage := 1
RETURN NIL
*****************
FUNCTION PSENDDOC(aCourriel, nCourriel, STOP)
*****************
SysRefresh()
IF oPrn != NIL
RETOURNEDC(,.T.)
PageEnd( @oPrn )
SysRefresh()
PrintEnd( @oPrn, @STOP, @aCourriel, @nCourriel)
SysRefresh()
RETOURNEDC(,.T.)
SysRefresh()
ENDIF
ANCFONTE()
IF oFont != NIL
oFont:End()
oFont := NIL
ENDIF
SysRefresh()
nPage := 0
RETURN NIL
******************
FUNCTION PSSETUNIT( nNouvUnit )
******************
* Map modes pour SetMapMode()
#define MM_TEXT 1
#define MM_LOMETRIC 2
#define MM_HIMETRIC 3
#define MM_LOENGLISH 4
*#define MM_HIENGLISH 5
*#define MM_TWIPS 6
*#define MM_ISOTROPIC 7
*#define MM_ANISOTROPIC 8
#define APS_TEXT 0 // Unit is text coordinates (Row, Col)
#define APS_MILL 1 // Unit is millimeter
#define APS_CENT 2 // Unit is centimeter
#define APS_INCH 3 // Unit is inch
#define APS_PIXEL 4 // Unit is pixels
STATIC nUnit := 4
IF nNouvUnit != NIL
*oImprimeur(@oPrn)
IF nNouvUnit = 4 .OR. nNouvUnit = 0
* unité de mesure = Pixel
SetMapMode( oPrn:hDC, MM_TEXT )
ELSEIF nNouvUnit = 1
* unité de mesure = Millimètre
SetMapMode( oPrn:hDC, MM_HIMETRIC )
ELSEIF nNouvUnit = 2
* unité de mesure = Centimètre
SetMapMode( oPrn:hDC, MM_LOMETRIC )
ELSEIF nNouvUnit = 3
* unité de mesure = Pouce
SetMapMode( oPrn:hDC, MM_LOENGLISH )
ENDIF
nUnit := nNouvUnit
ENDIF
RETURN nUnit
********************
FUNCTION PSSETBORDER( EPAISSEUR, NRGBCOUL )
********************
STATIC TT := { 1, 0 }
LOCAL ANCTT := ACLONE(TT)
IF EPAISSEUR != NIL
TT[1] := EPAISSEUR
ENDIF
IF NRGBCOUL != NIL
TT[2] := NRGBCOUL
ENDIF
RETURN ACLONE(ANCTT)
***************
FUNCTION PSLINE(LIGD, COLD, LIGF, COLF, EPAISSEUR, nRGBCOUL)
***************
STATIC oPen
*oImprimeur(@oPrn)
oPen := TPen():New( PS_SOLID, PointToPix( MAX( oPrn:nLogPixelX(), oPrn:nLogPixelY()), ;
IIF(EPAISSEUR = NIL, PSSETBORDER()[1], EPAISSEUR) ), ;
IIF(nRGBCOUL = NIL, PSSETBORDER()[2], nRGBCOUL) )
oPrn:Line( LIGD, COLD, LIGF, COLF, oPen )
oPen:End()
RETURN NIL
******************
FUNCTION PSNEWPAGE()
******************
PageEnd( @oPrn )
SysRefresh()
nPage ++
PageBegin( @oPrn )
RETURN NIL
****************
FUNCTION PSABORT()
****************
* Stoppe le travail d'impression en cours (Annulation)
IF oPrn != NIL
PSENDDOC(,,.T.)
ENDIF
ANCFONTE()
IF oFont != NIL
oFont:End()
oFont := NIL
ENDIF
SysRefresh()
nPage := 0
RETURN NIL
*******************
FUNCTION PSSHUTDOWN()
*******************
* OK
RETURN NIL
*******************
FUNCTION RETOURNEDC(DOFFICE, INITIALISE)
*******************
IF INITIALISE != NIL
IF HDCFW != NIL
ReleaseDC( oWnd:hWnd )
HDCFW := NIL
ENDIF
ELSE
IF HDCFW = NIL
HDCFW := GETDC( oWnd:hWnd )
ELSEIF !EMPTY(DOFFICE)
IF !EMPTY(HDCFW)
ReleaseDC( oWnd:hWnd )
ENDIF
HDCFW := GETDC( oWnd:hWnd )
ENDIF
ENDIF
RETURN HDCFW
*******************
FUNCTION PSFORMPAPI(FORMATPAP, LARGPAGE, LONGPAGE)
*******************
* Fonction renvoyant le numéro de format de papier pour PageScript,
* correspondant au format choisi par l'utilisateur
* FORMATPAP est la lettre d'identification du format dans les logiciels ICIM développés par Badara THIAM
#INCLUDE "PSCRIPT.CH"
IF FORMATPAP = "A"
* A : Exécutive (7.25 x 10.5 pouces)
LARGPAGE := 184
LONGPAGE := 267
RETURN DMPAPER_EXECUTIVE
ELSEIF FORMATPAP = "B"
* B : Letter (8.5 x 11 pouces)
LARGPAGE := 216
LONGPAGE := 279
RETURN DMPAPER_LETTER
ELSEIF FORMATPAP = "C"
* C : Légal (8.5 x 14 pouces)
LARGPAGE := 216
LONGPAGE := 356
RETURN DMPAPER_LEGAL
ELSEIF FORMATPAP = "D"
* D : A4 (210 x 297 mm)
LARGPAGE := 210
LONGPAGE := 297
RETURN DMPAPER_A4
ELSEIF FORMATPAP = "E"
* E : A3 (297 x 420 mm)
LARGPAGE := 297
LONGPAGE := 420
RETURN DMPAPER_A3
ELSEIF FORMATPAP = "F"
* F : Enveloppe Monarch (3 7/8 x 7 1/2 pouces)
LARGPAGE := 190
LONGPAGE := 98
RETURN DMPAPER_ENV_MONARCH
ELSEIF FORMATPAP = "G"
* G : Enveloppe COM-10 (4 1/8 x 9 1/2 pouces)
LARGPAGE := 241
LONGPAGE := 105
RETURN DMPAPER_ENV_10
ELSEIF FORMATPAP = "H"
* H : Enveloppe DL (110 x 220 mm)
LARGPAGE := 220
LONGPAGE := 110
RETURN DMPAPER_ENV_DL
ELSEIF FORMATPAP = "I"
* I : Enveloppe C5 (162 x 229 mm)
LARGPAGE := 229
LONGPAGE := 162
RETURN DMPAPER_ENV_C5
ELSEIF FORMATPAP = "J"
* J : Enveloppe C4 (229 x 324 mm)
LARGPAGE := 229
LONGPAGE := 324
RETURN DMPAPER_ENV_C4
ELSEIF FORMATPAP = "K"
* K : Enveloppe C3 (324 x 458 mm)
LARGPAGE := 324
LONGPAGE := 458
RETURN DMPAPER_ENV_C3
ELSEIF FORMATPAP = "L"
* L : Enveloppe C6 (114 x 162 mm)
LARGPAGE := 162
LONGPAGE := 114
RETURN DMPAPER_ENV_C6
ELSEIF FORMATPAP = "M"
* M : Etiquette 1 (49 x 99 mm)
LARGPAGE := 99
LONGPAGE := 49
RETURN DMPAPER_USER
ENDIF
RETURN DMPAPER_A4
*******************
FUNCTION PSSetDevice( nDevice )
*******************
* Mémorise le type de sortie : Directe, vue avant impression, .pdf
* Si nDevice = 1 : la sortie est envoyée vers l'imprimante (direct printing)
* Si nDevice = 2 : la sortie est envoyée vers la vue avant impression (Preview)
* Si nDevice = 3 : la sortie est enregistrée dans un fichier .pdf. Le fichier doit être défini
* avec PSSetFileName() avant de démarer le travail d'impression
* Retourne : NIL si nDevice n'est pas NIL, ou la valeur actuelle si nDevice est NIL
STATIC nDev := 1
IF nDevice = NIL
RETURN nDev
ENDIF
nDev := nDevice
RETURN NIL
...and with ICIM, enjoy Printing !!!