1

Konu: Custom Paper Size hk.

Herkese merhabalar;

Özetle yapmak istediğim şöyle bir şey : sistemde tanımlı olan yazıcıma kullanıcı tanımlı  bir kağıt eklemek istiyorum ("Custom Paper").

Sergey Berezniker 'e ait aşağıdaki kodu buldum ama bir türlü sonuç alamadım. Bu konuda yardım alabileceğim kimse var mı?

Her durumda "Unable to Add Form MyCustopmForm1" hatası alıyorum.

http://www.berezniker.com/content/pages … nter-forms

Visual Fox Pro
* All sizes in inches

ooo = NEWOBJECT("AddPrinterForm", "AddPrinterForm.fxp")
IF NOT ooo.AddForm("MyCustomForm1", 5,7, lcPrinterName)
    ? ooo.cErrorMessage
    ? ooo.cApiErrorMessage
  * Error
ENDIF
 
*!*    * Delete just created form
*!*    ooo = NEWOBJECT("AddPrinterForm", "AddPrinterForm.fxp")
*!*    IF NOT ooo.DeleteForm("MyCustomForm1", lcPrinterName)
*!*        ? ooo.cErrorMessage
*!*        ? ooo.cApiErrorMessage
*!*      * Error
*!*    ENDIF
 
 
* All sizes in cm
ooo = NEWOBJECT("AddPrinterForm", "AddPrinterForm.fxp", "", "Metric")
IF NOT ooo.AddForm("MyCustomForm2", 15,17, lcPrinterName)
  * Error
ENDIF
 
*!*    * Delete just created form
*!*    ooo = NEWOBJECT("AddPrinterForm", "AddPrinterForm.fxp")
*!*    IF NOT ooo.DeleteForm("MyCustomForm2", lcPrinterName)
*!*        ? ooo.cErrorMessage
*!*        ? ooo.cApiErrorMessage
*!*      * Error
*!*    ENDIF
 
* AddPrinterForm.prg
DEFINE CLASS AddPrinterForm AS Custom
 
    HIDDEN cUnit, cPrinterName, nFormHeight, nFormWidth, nLeftMargin, ;
              nTopMargin, nRightMargin, nBottomMargin, nInch2mm, nCm2mm, nCoefficient, hHeap
 
    cUnit = "English"        && inches or Metric - cm's
    cPrinterName = ""
    nFormHeight = 0
    nFormWidth = 0
    nLeftMargin = 0
    nTopMargin = 0
    nRightMargin = 0
    nBottomMargin = 0
 
    cApiErrorMessage = ""
    cErrorMessage = ""
 
    nInch2mm = 25.4
    nCm2mm = 10
    nCoefficient = This.nInch2mm * 1000
 
    hHeap = 0
 
    * Win API support class
    oWas = NULL
 
    PROCEDURE Init(tcUnit)
    This.oWas = NEWOBJECT("WinApiSupport", "WinApiSupport.fxp")
    IF PCOUNT() = 1
        This.cUnit = PROPER(tcUnit)
    ENDIF
    This.LoadApiDlls()
    This.hHeap = HeapCreate(0, 4096, 0)
    * Use Windows default printer
    This.cPrinterName = SET("Printer",2)
    ENDPROC
 
    PROCEDURE cUnit_Assign(tcUnit)
    IF INLIST(tcUnit, "English", "Metric")
        This.cUnit = PROPER(tcUnit)
    ELSE
        RETURN   
    ENDIF
    * Calculate conversion coefficient
    This.nCoefficient = IIF(PROPER(This.cUnit) = "English", ;
                        This.nInch2mm, This.nCm2mm) * 1000
    ENDPROC
 
    PROCEDURE Destroy
    IF This.hHeap <> 0
        HeapDestroy(This.hHeap)
    ENDIF
 
    ENDPROC
 
    PROCEDURE SetFormMargins(tnLeft, tnTop, tnRight, tnBottom)
    WITH This
        .nLeftMargin     = tnLeft   * .nCoefficient
        .nTopMargin     = tnTop    * .nCoefficient
        .nRightMargin     = tnRight  * .nCoefficient
        .nBottomMargin     = tnBottom * .nCoefficient
    ENDWITH
    ENDPROC
 
    PROCEDURE AddForm(tcFormName, tnWidth, tnHeight, tcPrinterName)
    LOCAL lhPrinter, llOK, lcForm
 
    This.nFormWidth  = tnWidth  * This.nCoefficient
    This.nFormHeight = tnHeight * This.nCoefficient
    IF PCOUNT() > 3
        This.cPrinterName = tcPrinterName
    ENDIF
 
    This.ClearErrors()
    lhPrinter = 0
    IF OpenPrinter(This.cPrinterName, @lhPrinter, 0) = 0
        This.cErrorMessage = "Unable to get printer handle for " + This.cPrinterName
        This.cApiErrorMessage = WinApiErrMsg(GetLastError())
        RETURN .F.
    ENDIF
 
    lnFormName = HeapAlloc(This.hHeap, 0, LEN(tcFormName) + 1)
    = SYS(2600, lnFormName, LEN(tcFormName) + 1, tcFormName + CHR(0))
 
    * Build FORM_INFO_1 structure
    WITH This.oWas
        lcForm = .Num2Long(0) + .Num2Long(lnFormName) + ;
            .Num2Long(This.nFormWidth) + .Num2Long(This.nFormHeight) + ;
            .Num2Long(This.nLeftMargin) + .Num2Long(This.nTopMargin) + ;
            .Num2Long(This.nFormWidth - This.nRightMargin) + ;
            .Num2Long(This.nFormHeight - This.nBottomMargin)
    ENDWITH
 
    * Finally, call the API
    IF AddForm(lhPrinter, 1, @lcForm) = 0
        This.cErrorMessage = "Unable to Add Form " + tcFormName
        This.cApiErrorMessage = STRTRAN(WinApiErrMsg(GetLastError()), "file", "form", -1, -1, 3)
        llOK = .F.
    ELSE
        llOK = .T.
    ENDIF
    = HeapFree(This.hHeap, 0, lnFormName)
    = ClosePrinter(lhPrinter)
 
    RETURN llOK
 
    PROCEDURE ClearErrors
    This.cErrorMessage = ""
    This.cApiErrorMessage = ""
    ENDPROC
 
    PROCEDURE DeleteForm(tcFormName, tcPrinterName)
    LOCAL lhPrinter, llOK
 
    IF PCOUNT() > 1
        This.cPrinterName = tcPrinterName
    ENDIF
 
    This.ClearErrors()
    lhPrinter = 0
    IF OpenPrinter(This.cPrinterName, @lhPrinter, 0) = 0
        This.cErrorMessage = "Unable to get printer handle for " + This.cPrinterName + "."
        This.cApiErrorMessage = WinApiErrMsg(GetLastError())
        RETURN .F.
    ENDIF
 
    * Finally, call the API
    llOK = ( DeleteForm(lhPrinter, tcFormName) <> 0 )
    IF NOT llOK
        This.cErrorMessage = "Unable to delete Form " + tcFormName
        This.cApiErrorMessage = STRTRAN(WinApiErrMsg(GetLastError()), "file", "form", -1, -1, 3)
    ENDIF
    = ClosePrinter(lhPrinter)
    RETURN llOK
 
    HIDDEN PROCEDURE LoadApiDlls
        DECLARE Long HeapCreate IN WIN32API Long dwOptions, Long dwInitialSize, Long dwMaxSize
        DECLARE Long HeapAlloc IN WIN32API Long hHeap, Long dwFlags, Long dwBytes
        DECLARE Long HeapFree IN WIN32API Long hHeap, Long dwFlags, Long lpMem
        DECLARE HeapDestroy IN WIN32API Long hHeap
        DECLARE Long GetLastError IN kernel32
    ENDPROC
 
ENDDEFINE
*----------------------------------------------------------------------------------------------
 
FUNCTION OpenPrinter(tcPrinterName, thPrinter, tcDefault)
DECLARE Long OpenPrinter IN WinSpool.Drv ;
    String pPrinterName, Long @ phPrinter, String pDefault
RETURN     OpenPrinter(tcPrinterName, @thPrinter, tcDefault)
 
FUNCTION ClosePrinter (thPrinter)
DECLARE Long ClosePrinter IN WinSpool.Drv Long hPrinter
RETURN ClosePrinter(thPrinter)
 
 
FUNCTION AddForm(thPrinter, tnLevel, tcForm)
DECLARE Long AddForm IN winspool.drv Long hPrinter, Long Level, String @pForm
RETURN AddForm(thPrinter, tnLevel, tcForm)
 
FUNCTION DeleteForm(thPrinter, tcForm)
DECLARE Long DeleteForm IN winspool.drv Long hPrinter, String  pFormName
RETURN DeleteForm(thPrinter, tcForm)
Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü

2

Re: Custom Paper Size hk.

Bazi degisikliklerle bende calisti:

1)

Visual Fox Pro
lcPrinterName=GetPrinter()

* All sizes in inches
ooo = NEWOBJECT("AddPrinterForm")
IF NOT ooo.AddForm("MyCustomForm1", 5,7, m.lcPrinterName)
    ? ooo.cErrorMessage
    ? ooo.cApiErrorMessage
  * Error
ENDIF
 
* All sizes in cm
ooo = NEWOBJECT("AddPrinterForm", "", "", "Metric")
IF NOT ooo.AddForm("MyCustomForm2", 15,17, lcPrinterName)
  * Error
ENDIF


2) Num2Long ekle:

Visual Fox Pro
Function Num2Long(tnValue)

Return BinToC(m.tnValue, '4RS')
EndFunc
 
 
* AddPrinterForm.prg
DEFINE CLASS AddPrinterForm AS Custom

3) oWas'i  olan her yerden kaldir, .Num2Long( lari, Num2Long( yap:

Visual Fox Pro
* Build FORM_INFO_1 structure

        lcForm = Num2Long(0) + Num2Long(lnFormName) + ;
            Num2Long(This.nFormWidth) + Num2Long(This.nFormHeight) + ;
            Num2Long(This.nLeftMargin) + Num2Long(This.nTopMargin) + ;
            Num2Long(This.nFormWidth - This.nRightMargin) + ;
            Num2Long(This.nFormHeight - This.nBottomMargin)

Hata almanin nedeni, zaten var olan bir formu gene tanimlamaya kalkismak ta olabilir.

3

Re: Custom Paper Size hk.

Üstat, sabah neşesi oldun smile
Sabah işlerini toparladıktan sonra hemen test edip sonucu vericem.

Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü

4 Son düzenleyen, ugurlu2001 (03.02.2012 14:00:14)

Re: Custom Paper Size hk.

Üstat kodu aşağıdaki şekilde düzenleyip çalıştırdım; ancak "Kağıt Tipi"ni (Custom Paper)  "her seferinde değiştirdiğimde" hata vermiyor . Hata vermediği durumda ise kod hiç bir ekleme / düzeltme yapmıyor. 

Bu ne kadar normal?

Not: Debug modunda; "lcForm" değişkeninde tuhaf ascii karakterler görünüyor!!

Visual Fox Pro
LOCAL lcPrinterName

 
m.lcPrinterName = GetPrinter()
 
SET STEP ON
 
* All sizes in cm
ooo = NEWOBJECT("AddPrinterForm", "", "", "Metric")
IF NOT ooo.AddForm("Ugur_Paper__002", 200,600, m.lcPrinterName)
  * Error
ENDIF
 
Function Num2Long(tnValue)
Return BinToC(m.tnValue, '4RS')
EndFunc
 
 
* AddPrinterForm.prg
DEFINE CLASS AddPrinterForm AS Custom
 
    HIDDEN cUnit, cPrinterName, nFormHeight, nFormWidth, nLeftMargin, ;
              nTopMargin, nRightMargin, nBottomMargin, nInch2mm, nCm2mm, nCoefficient, hHeap
 
    cUnit = "English"        && inches or Metric - cm's
    cPrinterName = ""
    nFormHeight = 0
    nFormWidth = 0
    nLeftMargin = 0
    nTopMargin = 0
    nRightMargin = 0
    nBottomMargin = 0
 
    cApiErrorMessage = ""
    cErrorMessage = ""
 
    nInch2mm = 25.4
    nCm2mm = 10
    nCoefficient = This.nInch2mm * 1000
 
    hHeap = 0
 
    * Win API support class
*!*        oWas = NULL
 
    PROCEDURE Init(tcUnit)
*!*        This.oWas = NEWOBJECT("WinApiSupport", "WinApiSupport.fxp")
    IF PCOUNT() = 1
        This.cUnit = PROPER(tcUnit)
    ENDIF
    This.LoadApiDlls()
    This.hHeap = HeapCreate(0, 4096, 0)
    * Use Windows default printer
    This.cPrinterName = SET("Printer",2)
    ENDPROC
 
    PROCEDURE cUnit_Assign(tcUnit)
    IF INLIST(tcUnit, "English", "Metric")
        This.cUnit = PROPER(tcUnit)
    ELSE
        RETURN   
    ENDIF
    * Calculate conversion coefficient
    This.nCoefficient = IIF(PROPER(This.cUnit) = "English", ;
                        This.nInch2mm, This.nCm2mm) * 1000
    ENDPROC
 
    PROCEDURE Destroy
    IF This.hHeap <> 0
        HeapDestroy(This.hHeap)
    ENDIF
 
    ENDPROC
 
    PROCEDURE SetFormMargins(tnLeft, tnTop, tnRight, tnBottom)
    WITH This
        .nLeftMargin     = tnLeft   * .nCoefficient
        .nTopMargin     = tnTop    * .nCoefficient
        .nRightMargin     = tnRight  * .nCoefficient
        .nBottomMargin     = tnBottom * .nCoefficient
    ENDWITH
    ENDPROC
 
    PROCEDURE AddForm(tcFormName, tnWidth, tnHeight, tcPrinterName)
    LOCAL lhPrinter, llOK, lcForm
 
    This.nFormWidth  = tnWidth  * This.nCoefficient
    This.nFormHeight = tnHeight * This.nCoefficient
    IF PCOUNT() > 3
        This.cPrinterName = tcPrinterName
    ENDIF
 
    This.ClearErrors()
    lhPrinter = 0
    IF OpenPrinter(This.cPrinterName, @lhPrinter, 0) = 0
        This.cErrorMessage = "Unable to get printer handle for " + This.cPrinterName
        This.cApiErrorMessage = WinApiErrMsg(GetLastError())
        RETURN .F.
    ENDIF
 
    lnFormName = HeapAlloc(This.hHeap, 0, LEN(tcFormName) + 1)
    = SYS(2600, lnFormName, LEN(tcFormName) + 1, tcFormName + CHR(0))
 
    * Build FORM_INFO_1 structure
*!*        WITH This.oWas
*!*            lcForm = .Num2Long(0) + .Num2Long(lnFormName) + ;
*!*                .Num2Long(This.nFormWidth) + .Num2Long(This.nFormHeight) + ;
*!*                .Num2Long(This.nLeftMargin) + .Num2Long(This.nTopMargin) + ;
*!*                .Num2Long(This.nFormWidth - This.nRightMargin) + ;
*!*                .Num2Long(This.nFormHeight - This.nBottomMargin)
*!*        ENDWITH
 
lcForm = Num2Long(0) + Num2Long(lnFormName) + ;
    Num2Long(This.nFormWidth) + Num2Long(This.nFormHeight) + ;
    Num2Long(This.nLeftMargin) + Num2Long(This.nTopMargin) + ;
    Num2Long(This.nFormWidth - This.nRightMargin) + ;
    Num2Long(This.nFormHeight - This.nBottomMargin)
 
 
    * Finally, call the API
    IF AddForm(lhPrinter, 1, @lcForm) = 0
        This.cErrorMessage = "Unable to Add Form " + tcFormName
        This.cApiErrorMessage = STRTRAN(WinApiErrMsg(GetLastError()), "file", "form", -1, -1, 3)
        llOK = .F.
    ELSE
        llOK = .T.
    ENDIF
    = HeapFree(This.hHeap, 0, lnFormName)
    = ClosePrinter(lhPrinter)
 
    RETURN llOK
 
    PROCEDURE ClearErrors
    This.cErrorMessage = ""
    This.cApiErrorMessage = ""
    ENDPROC
 
    PROCEDURE DeleteForm(tcFormName, tcPrinterName)
    LOCAL lhPrinter, llOK
 
    IF PCOUNT() > 1
        This.cPrinterName = tcPrinterName
    ENDIF
 
    This.ClearErrors()
    lhPrinter = 0
    IF OpenPrinter(This.cPrinterName, @lhPrinter, 0) = 0
        This.cErrorMessage = "Unable to get printer handle for " + This.cPrinterName + "."
        This.cApiErrorMessage = WinApiErrMsg(GetLastError())
        RETURN .F.
    ENDIF
 
    * Finally, call the API
    llOK = ( DeleteForm(lhPrinter, tcFormName) <> 0 )
    IF NOT llOK
        This.cErrorMessage = "Unable to delete Form " + tcFormName
        This.cApiErrorMessage = STRTRAN(WinApiErrMsg(GetLastError()), "file", "form", -1, -1, 3)
    ENDIF
    = ClosePrinter(lhPrinter)
    RETURN llOK
 
    HIDDEN PROCEDURE LoadApiDlls
        DECLARE Long HeapCreate IN WIN32API Long dwOptions, Long dwInitialSize, Long dwMaxSize
        DECLARE Long HeapAlloc IN WIN32API Long hHeap, Long dwFlags, Long dwBytes
        DECLARE Long HeapFree IN WIN32API Long hHeap, Long dwFlags, Long lpMem
        DECLARE HeapDestroy IN WIN32API Long hHeap
        DECLARE Long GetLastError IN kernel32
    ENDPROC
 
ENDDEFINE
*----------------------------------------------------------------------------------------------
 
FUNCTION OpenPrinter(tcPrinterName, thPrinter, tcDefault)
DECLARE Long OpenPrinter IN WinSpool.Drv ;
    String pPrinterName, Long @ phPrinter, String pDefault
RETURN     OpenPrinter(tcPrinterName, @thPrinter, tcDefault)
 
FUNCTION ClosePrinter (thPrinter)
DECLARE Long ClosePrinter IN WinSpool.Drv Long hPrinter
RETURN ClosePrinter(thPrinter)
 
 
FUNCTION AddForm(thPrinter, tnLevel, tcForm)
DECLARE Long AddForm IN winspool.drv Long hPrinter, Long Level, String @pForm
RETURN AddForm(thPrinter, tnLevel, tcForm)
 
FUNCTION DeleteForm(thPrinter, tcForm)
DECLARE Long DeleteForm IN winspool.drv Long hPrinter, String  pFormName
RETURN DeleteForm(thPrinter, tcForm)
Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü

5

Re: Custom Paper Size hk.

Degistirdiginde hata vermeyip ekliyordur. Orada 200,600 goruyorum. 2*6 mt kagit destekleyen printer yok bildigim kadariyla. Sanirim yazicinin destekledigi boyutlari astigin icin kuramiyor ya da kuruyor sen farketmiyorsun. Printer properties, Advanced'ten baktin mi? lcForm binary deger zaten, bir dizi integer degerin memorydeki hali string olarak (Num2Long demis ama aslinda Num2Dword ya da Num2Int daha dogru, o struct icindeki degerler dword).

6

Re: Custom Paper Size hk.

Üstat, 200 ve 600 ü mm cinsinden denemiştim, acaba olurmu diye.  Ama 20,15 gibi bir değer yaptığımda da değişmiyor sonuç.

Aslında ;

Visual Fox Pro
IF NOT ooo.AddForm("Ugur_Paper__002", 20,15, m.lcPrinterName)

satırındaki "Ugur_Paper__002" değerini her seferinde değiştirmezsem hata alıyorum. Yani bir yerlerde bir kağıt tipi ekleniyor. Ama her nedense ben o kağıt tipini göremiyorum.

Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü

7

Re: Custom Paper Size hk.

bence elle ekle gitsin. o kadar kasmaya gerek yok. yine de illa custom paper yapmak istiyorsan xfrx'i kullanabilirsin. custom paper boyunda rapor yapabiliyorsun. bir demo versiyonunu dene istersen.

Haksızlıklar karşısında susanlar, dilsiz şeytanlardır!
www.metinemre.com

8 Son düzenleyen, ugurlu2001 (04.02.2012 10:01:49)

Re: Custom Paper Size hk.

Kullanıcıya 0 ( sıfır ) insiyatif bırakmak istiyorum. Arka planda her şey olsun bitsin; Sonra kullanıcı daha önceden seçili kağıt tipi neyse onunla devam etsin. Temel olarak yapmak istediğim bu.

Aslında şöyle bir çözümde düşünebilirim :

-Raporlama öncesi "Custom Paper" seçilir
-Kağıt boyutunu ben istediğim cinsten ayarlarım
-Raporumu yazdırırım
-Raporlama öncesi default değerlere geri dönerim

Galiba her durumda oldukça uğraştırıcak.

Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü

9

Re: Custom Paper Size hk.

Üstat, haklıymışsın. Söylediğin gibi tüm kağıt tipleri eklenmiş. Kodları biraz gözden geçirmem ve derlemem gerekiyor. smile

Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü