我用VB打印前,如何知道当前打印机是否就绪?另请教高手们我用printform是为什么只能打印画面的一半?
有什么方法可以解决?
望不吝赐教!谢谢!!!

解决方案 »

  1.   

    详细请看
    http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q160/1/29.asp&NoWebContent=1Private Declare Function GetPrinterApi Lib "winspool.drv" Alias _ 
    "GetPrinterA" (ByVal hPrinter As Long, _ 
    ByVal Level As Long, _ 
    buffer As Long, _ 
    ByVal pbSize As Long, _ 
    pbSizeNeeded As Long) As Long 
    Private Type PRINTER_DEFAULTS 
    pDatatype As String 
    pDevMode As DEVMODE 
    DesiredAccess As Long 
    End Type Private Declare Function OpenPrinter Lib "winspool.drv" _ 
    Alias "OpenPrinterA" (ByVal pPrinterName As String, _ 
    phPrinter As Long, pDefault As PRINTER_DEFAULTS) As Long Private Declare Function ClosePrinter Lib "winspool.drv" _ 
    (ByVal hPrinter As Long) As Long ‘You pass the Printer.DeviceName to this to get the handle. Dim lret As Long 
    Dim pDef As PRINTER_DEFAULTS lret = OpenPrinter(Printer.DeviceName, mhPrinter, pDef) There are a number of standard statuses that can be returned by the printer driver. Public Enum Printer_Status 
    PRINTER_STATUS_READY = &H0 
    PRINTER_STATUS_PAUSED = &H1 
    PRINTER_STATUS_ERROR = &H2 
    PRINTER_STATUS_PENDING_DELETION = &H4 
    PRINTER_STATUS_PAPER_JAM = &H8 
    PRINTER_STATUS_PAPER_OUT = &H10 
    PRINTER_STATUS_MANUAL_FEED = &H20 
    PRINTER_STATUS_PAPER_PROBLEM = &H40 
    PRINTER_STATUS_OFFLINE = &H80 
    PRINTER_STATUS_IO_ACTIVE = &H100 
    PRINTER_STATUS_BUSY = &H200 
    PRINTER_STATUS_PRINTING = &H400 
    PRINTER_STATUS_OUTPUT_BIN_FULL = &H800 
    PRINTER_STATUS_NOT_AVAILABLE = &H1000 
    PRINTER_STATUS_WAITING = &H2000 
    PRINTER_STATUS_PROCESSING = &H4000 
    PRINTER_STATUS_INITIALIZING = &H8000 
    PRINTER_STATUS_WARMING_UP = &H10000 
    PRINTER_STATUS_TONER_LOW = &H20000 
    PRINTER_STATUS_NO_TONER = &H40000 
    PRINTER_STATUS_PAGE_PUNT = &H80000 
    PRINTER_STATUS_USER_INTERVENTION = &H100000 
    PRINTER_STATUS_OUT_OF_MEMORY = &H200000 
    PRINTER_STATUS_DOOR_OPEN = &H400000 
    PRINTER_STATUS_SERVER_UNKNOWN = &H800000 
    PRINTER_STATUS_POWER_SAVE = &H1000000 
    End Enum As each printer driver is responsible for returning this data there has to be a standard to which this returned data conforms in order for one application to be able to query a number of different types of printers. As it happens, there are nine different standard data types that can be returned by the GetPrinter API call in Windows 2000 (only the first two are universal to all current versions of Windows). 
    Of these, the second is the most interesting - named PRINTER_INFO_2 Private Type PRINTER_INFO_2 
    pServerName As String 
    pPrinterName As String 
    pShareName As String 
    pPortName As String 
    pDriverName As String 
    pComment As String 
    pLocation As String 
    pDevMode As Long 
    pSepFile As String 
    pPrintProcessor As String 
    pDatatype As String 
    pParameters As String 
    pSecurityDescriptor As Long 
    Attributes As Long 
    Priority As Long 
    DefaultPriority As Long 
    StartTime As Long 
    UntilTime As Long 
    Status As Long 
    JobsCount As Long 
    AveragePPM As Long 
    End Type However, it is not as simple as just passing this structure to the GetPrinter API call as a printer can return more information than is in that structure and if you do not allocate sufficent buffer space for it to do so your application will crash. 
    Fortunately the API call caters for this - if you pass zero in the pbSize parameter then the API call will tell you how big a buffer you will require in the pbSizeNeeded. 
    This means that filling the information from the printer driver becomes a two step process: Dim lret As Long 
    Dim SizeNeeded As Long Dim buffer() As Long ReDim Preserve buffer(0 To 1) As Long 
    lret = GetPrinterApi(mhPrinter, Index, buffer(0), UBound(buffer), SizeNeeded) 
    ReDim Preserve buffer(0 To (SizeNeeded / 4) + 3) As Long 
    lret = GetPrinterApi(mhPrinter, Index, buffer(0), UBound(buffer) * 4, SizeNeeded) 
    However the buffer is just an array of Long data types. Some of the data within the PRINTER_INFO_2 data structure is String data. This must be collected from the addresses which are stored in the appropriate buffer position. 
    To get a string from a pointer the CopyMemory API call is used and there is also an API call, IsBadStringPtr, which can be used to verify that the address pointed to does actually contain a valid string. '\\ Memory manipulation routines 
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) 
    '\\ Pointer validation in StringFromPointer 
    Private Declare Function IsBadStringPtrByLong Lib "kernel32" Alias "IsBadStringPtrA" (ByVal lpsz As Long, ByVal ucchMax As Long) As Long 
    Retrieving the string from a pointer is a common thing to have to do so it is worth having this utility function in your arsenal. Public Function StringFromPointer(lpString As Long, lMaxLength As Long) As String Dim sRet As String 
    Dim lret As Long If lpString = 0 Then 
    StringFromPointer = "" 
    Exit Function 
    End If If IsBadStringPtrByLong(lpString, lMaxLength) Then 
    '\\ An error has occured - do not attempt to use this pointer 
    StringFromPointer = "" 
    Exit Function 
    End If '\\ Pre-initialise the return string... 
    sRet = Space$(lMaxLength) 
    CopyMemory ByVal sRet, ByVal lpString, ByVal Len(sRet) 
    If Err.LastDllError = 0 Then 
    If InStr(sRet, Chr$(0)) > 0 Then 
    sRet = Left$(sRet, InStr(sRet, Chr$(0)) - 1) 
    End If 
    End If StringFromPointer = sRet End Function 
    So to use this to populate your PRINTER_INFO_2 variable: With mPRINTER_INFO_2 '\\ This variable is of type PRINTER_INFO_2 
    .pServerName = StringFromPointer(buffer(0), 1024) 
    .pPrinterName = StringFromPointer(buffer(1), 1024) 
    .pShareName = StringFromPointer(buffer(2), 1024) 
    .pPortName = StringFromPointer(buffer(3), 1024) 
    .pDriverName = StringFromPointer(buffer(4), 1024) 
    .pComment = StringFromPointer(buffer(5), 1024) 
    .pLocation = StringFromPointer(buffer(6), 1024) 
    .pDevMode = buffer(7) 
    .pSepFile = StringFromPointer(buffer(8), 1024) 
    .pPrintProcessor = StringFromPointer(buffer(9), 1024) 
    .pDatatype = StringFromPointer(buffer(10), 1024) 
    .pParameters = StringFromPointer(buffer(11), 1024) 
    .pSecurityDescriptor = buffer(12) 
    .Attributes = buffer(13) 
    .Priority = buffer(14) 
    .DefaultPriority = buffer(15) 
    .StartTime = buffer(16) 
    .UntilTime = buffer(17) 
    .Status = buffer(18) 
    .JobsCount = buffer(19) 
    .AveragePPM = buffer(20) 
    End With 基本上就是这个意思你自己整理一下
    ==天下本无事,庸人自扰之==
    试着自己找方法解决问题比提出问题后等着别人给答案的人,更让人有想帮助
    的感觉,所以试着自己解决问题,你会有意想不到的收获!
    [email protected]