1
« en: Martes 16 de Septiembre de 2003, 09:36 »
ups MIra este es un tema realmente complicado que requiere un nivel de programacion realmente avanzado
Para empezar dejame decirte que tendrias que hacer un servicio .que estaria corriendo en la maquina que controle la impresora entre otras cosas
dentro de este servicio tendrias que tener un modulo de clase que te permitiera contar los trabajos y hojas de determinada impresora o impresoras
al tener el usuario de ahi tomarias la direccion de ip que tambien llevaria algo de trabajo para leer los trabajos requeririas de las siguientes llamadas al Api de windows
Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrn As Long, pDefault As Any) As Long
Private Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrn As Long) As Long
Private Declare Function GetPrinter Lib "winspool.drv" Alias "GetPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, pPrinter As Any, ByVal cbBuf As Long, pcbNeeded As Long) As Long
Private Declare Function EnumJobs Lib "winspool.drv" Alias "EnumJobsA" (ByVal hPrinter As Long, ByVal FirstJob As Long, ByVal NoJobs As Long, ByVal Level As Long, pJob As Any, ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long
Private Declare Function SetJob Lib "winspool.drv" Alias "SetJobA" (ByVal hPrinter As Long, ByVal JobId As Long, ByVal Level As Long, pJob As Any, ByVal Command As Long) As Long
Private Declare Function GetJob Lib "winspool.drv" Alias "GetJobA" (ByVal hPrinter As Long, ByVal JobId As Long, ByVal Level As Long, pJob As Any, ByVal cdBuf As Long, pcbNeeded As Long) As Long
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
mas algunas Cosntantes y Tipos
te mando un modulo de clase que te resuelve en parte el problema de los trabajos del spooler de cierta impresora
pero solo es la solucion de una pequeña parte de este proyecto en el que te estas enfrascando.
Si decides realizarlo por ahi tengo otros modulos de clase que resuelven partes del problema global pero incisto es algo realmente complicado....
UPs no encontre como mandar un Archivo adjunto te escribo el codigo je je je
'Ingresa este codigo en un modulo de
' clase ejemplo cprinterjobs
Option Explicit
Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrn As Long, pDefault As Any) As Long
Private Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrn As Long) As Long
Private Declare Function GetPrinter Lib "winspool.drv" Alias "GetPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, pPrinter As Any, ByVal cbBuf As Long, pcbNeeded As Long) As Long
Private Declare Function EnumJobs Lib "winspool.drv" Alias "EnumJobsA" (ByVal hPrinter As Long, ByVal FirstJob As Long, ByVal NoJobs As Long, ByVal Level As Long, pJob As Any, ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long
Private Declare Function SetJob Lib "winspool.drv" Alias "SetJobA" (ByVal hPrinter As Long, ByVal JobId As Long, ByVal Level As Long, pJob As Any, ByVal Command As Long) As Long
Private Declare Function GetJob Lib "winspool.drv" Alias "GetJobA" (ByVal hPrinter As Long, ByVal JobId As Long, ByVal Level As Long, pJob As Any, ByVal cdBuf As Long, pcbNeeded As Long) As Long
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type
Private Const VER_PLATFORM_WIN32s = 0
Private Const VER_PLATFORM_WIN32_WINDOWS = 1
Private Const VER_PLATFORM_WIN32_NT = 2
Private Type PRINTER_DEFAULTS
pDatatype As String
pDevMode As Long
pDesiredAccess As Long
End Type
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const PRINTER_ACCESS_ADMINISTER = &H4
Private Const PRINTER_ACCESS_USE = &H8
Private Const PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE)
Private Const ERROR_INSUFFICIENT_BUFFER As Long = 122
Private Const JOB_CONTROL_PAUSE = 1
Private Const JOB_CONTROL_RESUME = 2
Private Const JOB_CONTROL_CANCEL = 3
Private Const JOB_CONTROL_RESTART = 4
Private Const JOB_CONTROL_DELETE = 5
Private Const JOB_CONTROL_SENT_TO_PRINTER = 6
Private Const JOB_CONTROL_LAST_PAGE_EJECTED = 7
Private Enum JobControlCodes
jcPause = JOB_CONTROL_PAUSE
jcResume = JOB_CONTROL_RESUME
jcCancel = JOB_CONTROL_CANCEL
jcRestart = JOB_CONTROL_RESTART
jcDelete = JOB_CONTROL_DELETE
End Enum
Private m_DevName As String
Private m_GetPrinterError As Long
Private m_jobs As Collection
Private Sub Class_Initialize()
Set m_jobs = New Collection
End Sub
Private Sub Class_Terminate()
Set m_jobs = Nothing
End Sub
Public Property Get DeviceName() As String
DeviceName = m_DevName
End Property
Public Property Let DeviceName(ByVal NewVal As String)
m_DevName = NewVal
Call Refresh
End Property
Public Property Get Count() As Long
Dim nRet As Long
nRet = JobCount()
If nRet <> m_jobs.Count Then
Call Refresh
End If
Count = nRet
End Property
Public Property Get Item(ByVal JobId As Variant) As CPrinterJobInfo
Set Item = m_jobs(JobId)
End Property
Public Property Get GetPrinterError() As Long
GetPrinterError = m_GetPrinterError
End Property
Public Function NewEnum() As IUnknown
Set NewEnum = m_jobs.[_NewEnum]
End Function
Public Function ControlCancel(ByVal JobId As Long) As Boolean
Dim os As OSVERSIONINFO
os.dwOSVersionInfoSize = Len(os)
Call GetVersionEx(os)
If os.dwPlatformId = VER_PLATFORM_WIN32_NT And os.dwMajorVersion >= 4 Then
ControlCancel = SendControl(JobId, jcDelete)
Else
ControlCancel = SendControl(JobId, jcCancel)
End If
End Function
Public Function ControlRestart(ByVal JobId As Long) As Boolean
ControlRestart = SendControl(JobId, jcRestart)
End Function
Public Function ControlResume(ByVal JobId As Long) As Boolean
ControlResume = SendControl(JobId, jcResume)
End Function
Public Function ControlPause(ByVal JobId As Long) As Boolean
ControlPause = SendControl(JobId, jcPause)
End Function
Public Function PositionMoveDown(ByVal JobId As Long) As Boolean
PositionMoveDown = AdjustJobPosition(JobId, 1)
End Function
Public Function PositionMoveUp(ByVal JobId As Long) As Boolean
PositionMoveUp = AdjustJobPosition(JobId, -1)
End Function
Public Sub Refresh()
Dim hPrn As Long
Dim nJobs As Long
Dim JobIds() As Long
Dim Buffer() As Byte
Dim BytesNeeded As Long
Dim nReturned As Long
Dim NewJob As CPrinterJobInfo
Dim OldJob As CPrinterJobInfo
Dim i As Long
Call OpenPrinter(m_DevName, hPrn, ByVal 0&)
If hPrn Then
nJobs = JobCount(hPrn)
If nJobs > 0 Then
ReDim JobIds(0 To nJobs - 1) As Long
Call EnumJobs(hPrn, 0, nJobs, 2, ByVal 0&, 0, BytesNeeded, nReturned)
If Err.LastDllError = ERROR_INSUFFICIENT_BUFFER Then
ReDim Buffer(0 To BytesNeeded - 1) As Byte
If EnumJobs(hPrn, 0, nJobs, 2, Buffer(0), BytesNeeded, BytesNeeded, nReturned) Then
For i = 0 To nReturned - 1
Set NewJob = New CPrinterJobInfo
NewJob.Initialize VarPtr(Buffer(0)), i
Set OldJob = GetJobInfo(NewJob.JobId)
If Not OldJob Is Nothing Then
NewJob.SizeMax = OldJob.SizeMax
NewJob.TotalPagesMax = OldJob.TotalPagesMax
m_jobs.Remove Hex$(OldJob.JobId)
End If
m_jobs.Add NewJob, Hex$(NewJob.JobId)
JobIds(i) = NewJob.JobId
Next i
End If
End If
End If
Call ClosePrinter(hPrn)
End If
For Each OldJob In m_jobs
If nJobs > 0 Then
For i = LBound(JobIds) To UBound(JobIds)
If OldJob.JobId = JobIds(i) Then Exit For
Next i
If i = UBound(JobIds) + 1 Then
m_jobs.Remove Hex$(OldJob.JobId)
End If
Else
m_jobs.Remove Hex$(OldJob.JobId)
End If
Next OldJob
End Sub
Private Function AdjustJobPosition(ByVal JobId As Long, ByVal Delta As Long) As Boolean
Dim pd As PRINTER_DEFAULTS
Dim hPrn As Long
Dim Buffer() As Byte
Dim BytesNeeded As Long
Dim Position As Long
pd.pDesiredAccess = PRINTER_ACCESS_ADMINISTER
Call OpenPrinter(m_DevName, hPrn, pd)
If hPrn Then
Call GetJob(hPrn, JobId, 1, ByVal 0&, 0&, BytesNeeded)
If Err.LastDllError = ERROR_INSUFFICIENT_BUFFER Then
ReDim Buffer(0 To BytesNeeded - 1) As Byte
If GetJob(hPrn, JobId, 1, Buffer(0), BytesNeeded, BytesNeeded) Then
Const PositionOffset As Long = 9 * 4&
Call CopyMemory(Position, Buffer(PositionOffset), 4&)
Position = Position + Delta
Call CopyMemory(Buffer(PositionOffset), Position, 4&)
AdjustJobPosition = CBool(SetJob(hPrn, JobId, 1, Buffer(0), 0))
End If
End If
Call ClosePrinter(hPrn)
End If
End Function
Private Function GetJobInfo(ByVal JobId As Long) As CPrinterJobInfo
On Error Resume Next
Set GetJobInfo = m_jobs(Hex$(JobId))
End Function
Private Function JobCount(Optional ByVal hPrn As Long = 0) As Long
Dim Buffer() As Byte
Dim BytesNeeded As Long
Dim BytesUsed As Long
Dim CloseHandle As Boolean
If hPrn = 0 Then
Call OpenPrinter(m_DevName, hPrn, ByVal 0&)
CloseHandle = True
End If
If hPrn Then
Call GetPrinter(hPrn, 2, ByVal 0&, 0, BytesNeeded)
If Err.LastDllError = ERROR_INSUFFICIENT_BUFFER Then
ReDim Buffer(0 To BytesNeeded - 1) As Byte
If GetPrinter(hPrn, 2, Buffer(0), BytesNeeded, BytesUsed) Then
Const JobsOffset As Long = 19 * 4&
Call CopyMemory(JobCount, Buffer(JobsOffset), 4&)
End If
m_GetPrinterError = 0
Else
m_GetPrinterError = Err.LastDllError
End If
End If
If CloseHandle Then Call ClosePrinter(hPrn)
End Function
Private Function SendControl(ByVal JobId As Long, ByVal ControlCode As JobControlCodes) As Boolean
Dim hPrn As Long
Call OpenPrinter(m_DevName, hPrn, ByVal 0&)
If hPrn Then
SendControl = CBool(SetJob(hPrn, JobId, 0, ByVal 0&, ControlCode))
Call ClosePrinter(hPrn)
Call Me.Refresh
End If
End Function
Espero te sirva de algo Saludos........
Y buena suerte en este Proyecto