views:

331

answers:

5

I am trying to set a custom paper size by doing:

Printer.Height = 2160
Printer.Width = 11900

But it doesn't seen to have any effect. After setting this up, i ask for that values and it returns the default ones. And this:

Printer.PaperSize = 256

Returns an error...

Any ideas??

+1  A: 

Either your printer doesn't allow these properties to be set, or you're exceeding their maximum allowed values. From the Visual Basic Reference

If you set the Height and Width properties for a printer driver that doesn't allow these properties to be set, no error occurs and the size of the paper remains as it was. If you set Height and Width for a printer driver that allows only certain values to be specified, no error occurs and the property is set to whatever the driver allows. For example, you could set Height to 150 and the driver would set it to 144.

I don't know why you're getting an error when you set the Papersize property to 256. It works for me. Also, the documentation states, "Setting a printer's Height or Width property automatically sets PaperSize to vbPRPSUser.", which equals 256.

raven
+1  A: 

Are you sure the error isn't related to the maximum print width of the printer itself? Many printers have a max print width of 8.25" (11880) to allow 1/4" margins on either side of a 8.5" wide paper.

Quickest way to check would be to simply set the print wide to 11880 or lower and see if it works.

Another possibility would be permissions to the printer. If it's a shared network resource it may be locked down.

jasonk
A: 

The solution is to use windows 98. It does not work with win2k, neither winXP. The same code, the same printer.

Regards.

mRt
A: 

I was actually involved with the same problem but I just happen to find a breakthrough. First you need to create a custom form that defines you custom paper size. Then, you need to refer to Windows API to check the form name you've just created. You'll get the for name from an array returned from a function and use the array index where the form name was found. Finally use it as the value for printer.papersize

Example below:

Public Type PRINTER_DEFAULTS
   pDatatype            As Long
   pDevMode             As Long
   DesiredAccess        As Long
End Type

Public Type FORM_INFO_1
        Flags As Long
        pName As Long   ' String
        Size As SIZEL
        ImageableArea As RECTL
End Type

Public Declare Function EnumForms Lib "winspool.drv" Alias "EnumFormsA" _
    (ByVal hPrinter As Long, ByVal Level As Long, ByRef pForm As Any, _
    ByVal cbBuf As Long, ByRef pcbNeeded As Long, _
    ByRef pcReturned As Long) As Long

Public Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" _
   (pDest As Any, pSource As Any, ByVal cbLength As Long)
Public Declare Sub Sleep Lib "KERNEL32" (ByVal dwMilliseconds As Long)

Public Declare Function OpenPrinter Lib "winspool.drv" Alias _
   "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, _
   pDefault As PRINTER_DEFAULTS) As Long

Public Declare Function ClosePrinter Lib "winspool.drv" _
   (ByVal hPrinter As Long) As Long

Public Declare Function lstrcpy Lib "KERNEL32" Alias "lstrcpyA" _
    (ByVal lpString1 As String, ByRef lpString2 As Long) As Long

'UDF
Public Function PtrCtoVbString(ByVal Add As Long) As String
Dim sTemp As String * 512, x As Long

x = lstrcpy(sTemp, ByVal Add)
If (InStr(1, sTemp, Chr(0)) = 0) Then
     PtrCtoVbString = ""
Else
     PtrCtoVbString = Left(sTemp, InStr(1, sTemp, Chr(0)) - 1)
End If
End Function

Public Function IsFormExist(ByVal DeviceName As String, ByVal isFormName As String, ByVal PrinterHandle As Long) As Long
Dim NumForms As Long, i As Long
Dim FI1 As FORM_INFO_1
Dim pd As PRINTER_DEFAULTS
Dim aFI1() As FORM_INFO_1           ' Working FI1 array
Dim Temp() As Byte                  ' Temp FI1 array
Dim FormIndex As Integer
Dim BytesNeeded As Long
Dim RetVal As Long

On Error GoTo cleanup

FormIndex = 0
ReDim aFI1(1)
' First call retrieves the BytesNeeded.

RetVal = OpenPrinter(DeviceName, PrinterHandle, pd)
  If (RetVal = 0) Or (PrinterHandle = 0) Then
  'Can't access current printer. Bail out doing nothing
  Exit Function
End If

RetVal = EnumForms(PrinterHandle, 1, aFI1(0), 0&, BytesNeeded, NumForms)
ReDim Temp(BytesNeeded)
ReDim aFI1(BytesNeeded / Len(FI1))
' Second call actually enumerates the supported forms.
RetVal = EnumForms(PrinterHandle, 1, Temp(0), BytesNeeded, BytesNeeded, _
         NumForms)
Call CopyMemory(aFI1(0), Temp(0), BytesNeeded)
For i = 0 To NumForms - 1
    With aFI1(i)
        If isFormName = PtrCtoVbString(.pName) Then
           ' Found the desired form
            FormIndex = i + 1
            Exit For
        End If
    End With
Next i
IsFormExist = FormIndex ' Returns the number when form is found.

cleanup:
   'Release the printer handle
   If (PrinterHandle <> 0) Then Call ClosePrinter(PrinterHandle)
End Function


'Here We Go

dim papercode as long, printername as string, formname as string
printername=printer.Devicename 
formname = "myform"   

papercode=IsFormExist(printername, formname, Printer.hdc)

if papercode<>0 then
  printer.papersize=papercode
end if

Give it a try, good luck

zulridzwan
A: 

Hello, I'm testing this code, but I can not see the custom form I created using printers and scanners in the Control Panel Windows XP Professional SP3. Note: I could check in regedit that this form exists and its ID is 512 in a string value and it contains the name of the form created in the printers control panel.

Why this function does not return my custom form, I am using an HP Laserjet 1020.

MyDesc