PDA

View Full Version : کنترل چاپگر های سیستم



daniyal_1363
یک شنبه 23 مرداد 1390, 17:14 عصر
سلام

کسی میدونه چه جوری میشه پرینتر های سیستم رو کنترل کنیم و اطلاعات ازشون بگیریم ؟

مهمترین مسئله من اینکه بدونم چه جوری میتونم وقتی کاربر پرینت میگیره تعداد برگ پرینتش رو بدست بیارم ؟

:متفکر:

returnx
یک شنبه 23 مرداد 1390, 18:15 عصر
VB6 یک شی ای داره به نام printer که میتونید از این شی برای مدیریت چاپگر ها استفاده کنید ، فکر میکنم چییز هایی که نیاز داشته باشین رو بهتون بده...
فقط کافیه بنویسید printer و بعد . رو بزنید...

quiet_programmer
یک شنبه 23 مرداد 1390, 18:27 عصر
با سلام.

دیگه من تاپیک جدید ایجاد نکردم. این مشکل من هم هست. بزارین به یه شکل دیگه بگم. من میخوام (احتمالا جناب daniyal_1363 (http://barnamenevis.org/member.php?26986-daniyal_1363) هم همینو میخوان) یه برنامه از زمان اجرای ویندوز تا اتمام در حالت اجرا باشه و بافر پرینتر رو چک کنه و تمامی پرینت هایی که صورت میگیرن رو log کنه.

(البته اگه جناب daniyal_1363 (http://barnamenevis.org/member.php?26986-daniyal_1363) عزیز این چیزی که من گفتم مد نظر شما نبوده اطلاع بدین تا من یه تاپیک جدید بزنم.مرسی)

quiet_programmer
یک شنبه 23 مرداد 1390, 18:32 عصر
VB6 یک شی ای داره به نام printer که میتونید از این شی برای مدیریت چاپگر ها استفاده کنید ، فکر میکنم چییز هایی که نیاز داشته باشین رو بهتون بده...
فقط کافیه بنویسید printer و بعد . رو بزنید... بنده این شی رو برسی کردم ولی احتمالا این فقط برای پرینتهایی باشه که با برنامه نوشته شده، ارسال به پرینتر شده اند. یعنی نمیتونه هیچ کنترلی بر روی پرینت های دیگه از برنامه های مختلف مثل ورد یا نودپد و ... داشته باشه.

quiet_programmer
یک شنبه 23 مرداد 1390, 20:12 عصر
یافتم...یافتم...:لبخند:


این مراحل رو از لینک زیر براتون میزارم. البته چون برای اینکه صفحه عوض نکنید مراحلش رو همینجا کپی پیست میکنم. برنامش رو هم در انتها ضمیمه کردم.

http://support.microsoft.com/kb/202480

مراحل:

Step-by-Step Example



Create a new Standard EXE project in Visual Basic. By default, Form1 is created.
On the Project menu, click Add Module, and then add the following code



:Option Explicit

Public Declare Function lstrcpy Lib "kernel32" _
Alias "lstrcpyA" _
(ByVal lpString1 As String, _
ByVal lpString2 As String) _
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 GetPrinter Lib "winspool.drv" Alias "GetPrinterA" _
(ByVal hPrinter As Long, _
ByVal Level As Long, _
pPrinter As Byte, _
ByVal cbBuf As Long, _
pcbNeeded As Long) _
As Long

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

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)

Public 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 Byte, _
ByVal cdBuf As Long, _
pcbNeeded As Long, _
pcReturned As Long) _
As Long

' constants for PRINTER_DEFAULTS structure
Public Const PRINTER_ACCESS_USE = &H8
Public Const PRINTER_ACCESS_ADMINISTER = &H4

' constants for DEVMODE structure
Public Const CCHDEVICENAME = 32
Public Const CCHFORMNAME = 32

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

Public Type DEVMODE
dmDeviceName As String * CCHDEVICENAME
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName As String * CCHFORMNAME
dmLogPixels As Integer
dmBitsPerPel As Long
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
End Type

Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type

Type JOB_INFO_2
JobId As Long
pPrinterName As Long
pMachineName As Long
pUserName As Long
pDocument As Long
pNotifyName As Long
pDatatype As Long
pPrintProcessor As Long
pParameters As Long
pDriverName As Long
pDevMode As Long
pStatus As Long
pSecurityDescriptor As Long
Status As Long
Priority As Long
Position As Long
StartTime As Long
UntilTime As Long
TotalPages As Long
Size As Long
Submitted As SYSTEMTIME
time As Long
PagesPrinted As Long
End Type

Type PRINTER_INFO_2
pServerName As Long
pPrinterName As Long
pShareName As Long
pPortName As Long
pDriverName As Long
pComment As Long
pLocation As Long
pDevMode As Long
pSepFile As Long
pPrintProcessor As Long
pDatatype As Long
pParameters As Long
pSecurityDescriptor As Long
Attributes As Long
Priority As Long
DefaultPriority As Long
StartTime As Long
UntilTime As Long
Status As Long
cJobs As Long
AveragePPM As Long
End Type

Public Const ERROR_INSUFFICIENT_BUFFER = 122
Public Const PRINTER_STATUS_BUSY = &H200
Public Const PRINTER_STATUS_DOOR_OPEN = &H400000
Public Const PRINTER_STATUS_ERROR = &H2
Public Const PRINTER_STATUS_INITIALIZING = &H8000
Public Const PRINTER_STATUS_IO_ACTIVE = &H100
Public Const PRINTER_STATUS_MANUAL_FEED = &H20
Public Const PRINTER_STATUS_NO_TONER = &H40000
Public Const PRINTER_STATUS_NOT_AVAILABLE = &H1000
Public Const PRINTER_STATUS_OFFLINE = &H80
Public Const PRINTER_STATUS_OUT_OF_MEMORY = &H200000
Public Const PRINTER_STATUS_OUTPUT_BIN_FULL = &H800
Public Const PRINTER_STATUS_PAGE_PUNT = &H80000
Public Const PRINTER_STATUS_PAPER_JAM = &H8
Public Const PRINTER_STATUS_PAPER_OUT = &H10
Public Const PRINTER_STATUS_PAPER_PROBLEM = &H40
Public Const PRINTER_STATUS_PAUSED = &H1
Public Const PRINTER_STATUS_PENDING_DELETION = &H4
Public Const PRINTER_STATUS_PRINTING = &H400
Public Const PRINTER_STATUS_PROCESSING = &H4000
Public Const PRINTER_STATUS_TONER_LOW = &H20000
Public Const PRINTER_STATUS_USER_INTERVENTION = &H100000
Public Const PRINTER_STATUS_WAITING = &H2000
Public Const PRINTER_STATUS_WARMING_UP = &H10000
Public Const JOB_STATUS_PAUSED = &H1
Public Const JOB_STATUS_ERROR = &H2
Public Const JOB_STATUS_DELETING = &H4
Public Const JOB_STATUS_SPOOLING = &H8
Public Const JOB_STATUS_PRINTING = &H10
Public Const JOB_STATUS_OFFLINE = &H20
Public Const JOB_STATUS_PAPEROUT = &H40
Public Const JOB_STATUS_PRINTED = &H80
Public Const JOB_STATUS_DELETED = &H100
Public Const JOB_STATUS_BLOCKED_DEVQ = &H200
Public Const JOB_STATUS_USER_INTERVENTION = &H400
Public Const JOB_STATUS_RESTART = &H800

Public Function GetString(ByVal PtrStr As Long) As String
Dim StrBuff As String * 256

'Check for zero address
If PtrStr = 0 Then
GetString = " "
Exit Function
End If

'Copy data from PtrStr to buffer.
CopyMemory ByVal StrBuff, ByVal PtrStr, 256

'Strip any trailing nulls from string.
GetString = StripNulls(StrBuff)
End Function

Public Function StripNulls(OriginalStr As String) As String
'Strip any trailing nulls from input string.
If (InStr(OriginalStr, Chr(0)) > 0) Then
OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
End If

'Return modified string.
StripNulls = OriginalStr
End Function

Public Function PtrCtoVbString(Add As Long) As String
Dim sTemp As String * 512
Dim x As Long

x = lstrcpy(sTemp, 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 CheckPrinterStatus(PI2Status As Long) As String
Dim tempStr As String

If PI2Status = 0 Then ' Return "Ready"
CheckPrinterStatus = "Printer Status = Ready" & vbCrLf
Else
tempStr = "" ' Clear
If (PI2Status And PRINTER_STATUS_BUSY) Then
tempStr = tempStr & "Busy "
End If

If (PI2Status And PRINTER_STATUS_DOOR_OPEN) Then
tempStr = tempStr & "Printer Door Open "
End If

If (PI2Status And PRINTER_STATUS_ERROR) Then
tempStr = tempStr & "Printer Error "
End If

If (PI2Status And PRINTER_STATUS_INITIALIZING) Then
tempStr = tempStr & "Initializing "
End If

If (PI2Status And PRINTER_STATUS_IO_ACTIVE) Then
tempStr = tempStr & "I/O Active "
End If

If (PI2Status And PRINTER_STATUS_MANUAL_FEED) Then
tempStr = tempStr & "Manual Feed "
End If

If (PI2Status And PRINTER_STATUS_NO_TONER) Then
tempStr = tempStr & "No Toner "
End If

If (PI2Status And PRINTER_STATUS_NOT_AVAILABLE) Then
tempStr = tempStr & "Not Available "
End If

If (PI2Status And PRINTER_STATUS_OFFLINE) Then
tempStr = tempStr & "Off Line "
End If

If (PI2Status And PRINTER_STATUS_OUT_OF_MEMORY) Then
tempStr = tempStr & "Out of Memory "
End If

If (PI2Status And PRINTER_STATUS_OUTPUT_BIN_FULL) Then
tempStr = tempStr & "Output Bin Full "
End If

If (PI2Status And PRINTER_STATUS_PAGE_PUNT) Then
tempStr = tempStr & "Page Punt "
End If

If (PI2Status And PRINTER_STATUS_PAPER_JAM) Then
tempStr = tempStr & "Paper Jam "
End If

If (PI2Status And PRINTER_STATUS_PAPER_OUT) Then
tempStr = tempStr & "Paper Out "
End If

If (PI2Status And PRINTER_STATUS_OUTPUT_BIN_FULL) Then
tempStr = tempStr & "Output Bin Full "
End If

If (PI2Status And PRINTER_STATUS_PAPER_PROBLEM) Then
tempStr = tempStr & "Page Problem "
End If

If (PI2Status And PRINTER_STATUS_PAUSED) Then
tempStr = tempStr & "Paused "
End If

If (PI2Status And PRINTER_STATUS_PENDING_DELETION) Then
tempStr = tempStr & "Pending Deletion "
End If

If (PI2Status And PRINTER_STATUS_PRINTING) Then
tempStr = tempStr & "Printing "
End If

If (PI2Status And PRINTER_STATUS_PROCESSING) Then
tempStr = tempStr & "Processing "
End If

If (PI2Status And PRINTER_STATUS_TONER_LOW) Then
tempStr = tempStr & "Toner Low "
End If

If (PI2Status And PRINTER_STATUS_USER_INTERVENTION) Then
tempStr = tempStr & "User Intervention "
End If

If (PI2Status And PRINTER_STATUS_WAITING) Then
tempStr = tempStr & "Waiting "
End If

If (PI2Status And PRINTER_STATUS_WARMING_UP) Then
tempStr = tempStr & "Warming Up "
End If

'Did you find a known status?
If Len(tempStr) = 0 Then
tempStr = "Unknown Status of " & PI2Status
End If

'Return the Status
CheckPrinterStatus = "Printer Status = " & tempStr & vbCrLf
End If
End Function





Add three CommandButton controls.
Add three TextBox controls to Form1, and then configure the TextBox controls as follows:

Set the MultiLine property of each TextBox control to True.
Size each TextBox to approximately five inches wide and three inches long.
Set the ScrollBars property of each TextBox control to 2 - Vertical.


Add a Timer control to Form1.
Add the following code to the Form's module:



Option Explicit

Private Sub Command1_Click()
'Enable the timer to begin printer status checks.
Timer1.Enabled = True

'Enable and disable start and stop buttons.
Command1.Enabled = False
Command2.Enabled = True
Command3.Enabled = True
End Sub

Private Sub Command2_Click()
'Disable timer to stop further printer checks.
Timer1.Enabled = False

'Enable and disable start and stop buttons.
Command1.Enabled = True
Command2.Enabled = False
Command3.Enabled = True
End Sub

Private Sub Command3_Click()
'Clear the status info.
Text1.Text = ""
Text2.Text = ""
Text3.Text = ""
End Sub

Private Sub Form_Load()
'Initialize captions for control buttons.
Command1.Caption = "Start"
Command2.Caption = "Stop"
Command3.Caption = "Clear"

'Clear the status info.
Text1.Text = ""
Text2.Text = ""
Text3.Text = ""

Command1.Enabled = True
'Disable stop and clear buttons.
Command2.Enabled = False
Command3.Enabled = False

'Set interval for printer status checking to 1/2 second.
Timer1.Enabled = False
Timer1.Interval = 500
End Sub

Private Sub Timer1_Timer()
Dim PrinterStatus As String
Dim JobStatus As String
Dim ErrorInfo As String

'Clear the status info for new info/status.
Text1.Text = ""
Text2.Text = ""
Text3.Text = ""

'Call sub to perform check.
Text1.Text = CheckPrinter(PrinterStatus, JobStatus)
Text2.Text = PrinterStatus
Text3.Text = JobStatus
End Sub

Public Function CheckPrinter(PrinterStr As String, JobStr As String) As String
Dim hPrinter As Long
Dim ByteBuf As Long
Dim BytesNeeded As Long
Dim PI2 As PRINTER_INFO_2
Dim JI2 As JOB_INFO_2
Dim PrinterInfo() As Byte
Dim JobInfo() As Byte
Dim result As Long
Dim LastError As Long
Dim PrinterName As String
Dim tempStr As String
Dim NumJI2 As Long
Dim pDefaults As PRINTER_DEFAULTS
Dim I As Integer

'Set a default return value if no errors occur.
CheckPrinter = "Printer info retrieved"

'NOTE: You can pick a printer from the Printers Collection
'or use the EnumPrinters() API to select a printer name.

'Use the default printer of Printers collection.
'This is typically, but not always, the system default printer.
PrinterName = Printer.DeviceName

'Set desired access security setting.
pDefaults.DesiredAccess = PRINTER_ACCESS_USE

'Call API to get a handle to the printer.
result = OpenPrinter(PrinterName, hPrinter, pDefaults)
If result = 0 Then
'If an error occurred, display an error and exit sub.
CheckPrinter = "Cannot open printer " & PrinterName & _
", Error: " & Err.LastDllError
Exit Function
End If

'Init BytesNeeded
BytesNeeded = 0

'Clear the error object of any errors.
Err.Clear

'Determine the buffer size that is needed to get printer info.
result = GetPrinter(hPrinter, 2, 0&, 0&, BytesNeeded)

'Check for error calling GetPrinter.
If Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER Then
'Display an error message, close printer, and exit sub.
CheckPrinter = " > GetPrinter Failed on initial call! <"
ClosePrinter hPrinter
Exit Function
End If

'Note that in Charles Petzold's book "Programming Windows 95," he
'states that because of a problem with GetPrinter on Windows 95 only, you
'must allocate a buffer as much as three times larger than the value
'returned by the initial call to GetPrinter. This is not done here.
ReDim PrinterInfo(1 To BytesNeeded)

ByteBuf = BytesNeeded

'Call GetPrinter to get the status.
result = GetPrinter(hPrinter, 2, PrinterInfo(1), ByteBuf, _
BytesNeeded)

'Check for errors.
If result = 0 Then
'Determine the error that occurred.
LastError = Err.LastDllError()

'Display error message, close printer, and exit sub.
CheckPrinter = "Couldn't get Printer Status! Error = " _
& LastError
ClosePrinter hPrinter
Exit Function
End If

'Copy contents of printer status byte array into a
'PRINTER_INFO_2 structure to separate the individual elements.
CopyMemory PI2, PrinterInfo(1), Len(PI2)

'Check if printer is in ready state.
PrinterStr = CheckPrinterStatus(PI2.Status)

'Add printer name, driver, and port to list.
PrinterStr = PrinterStr & "Printer Name = " & _
GetString(PI2.pPrinterName) & vbCrLf
PrinterStr = PrinterStr & "Printer Driver Name = " & _
GetString(PI2.pDriverName) & vbCrLf
PrinterStr = PrinterStr & "Printer Port Name = " & _
GetString(PI2.pPortName) & vbCrLf

'Call API to get size of buffer that is needed.
result = EnumJobs(hPrinter, 0&, &HFFFFFFFF, 2, ByVal 0&, 0&, _
BytesNeeded, NumJI2)

'Check if there are no current jobs, and then display appropriate message.
If BytesNeeded = 0 Then
JobStr = "No Print Jobs!"
Else
'Redim byte array to hold info about print job.
ReDim JobInfo(0 To BytesNeeded)

'Call API to get print job info.
result = EnumJobs(hPrinter, 0&, &HFFFFFFFF, 2, JobInfo(0), _
BytesNeeded, ByteBuf, NumJI2)

'Check for errors.
If result = 0 Then
'Get and display error, close printer, and exit sub.
LastError = Err.LastDllError
CheckPrinter = " > EnumJobs Failed on second call! < Error = " _
& LastError
ClosePrinter hPrinter
Exit Function
End If

'Copy contents of print job info byte array into a
'JOB_INFO_2 structure to separate the individual elements.
For I = 0 To NumJI2 - 1 ' Loop through jobs and walk the buffer
CopyMemory JI2, JobInfo(I * Len(JI2)), Len(JI2)

' List info available on Jobs.
Debug.Print "Job ID" & vbTab & JI2.JobId
Debug.Print "Name Of Printer" & vbTab & _
GetString(JI2.pPrinterName)
Debug.Print "Name Of Machine That Created Job" & vbTab & _
GetString(JI2.pMachineName)
Debug.Print "Print Job Owner's Name" & vbTab & _
GetString(JI2.pUserName)
Debug.Print "Name Of Document" & vbTab & GetString(JI2.pDocument)
Debug.Print "Name Of User To Notify" & vbTab & _
GetString(JI2.pNotifyName)
Debug.Print "Type Of Data" & vbTab & GetString(JI2.pDatatype)
Debug.Print "Print Processor" & vbTab & _
GetString(JI2.pPrintProcessor)
Debug.Print "Print Processor Parameters" & vbTab & _
GetString(JI2.pParameters)
Debug.Print "Print Driver Name" & vbTab & _
GetString(JI2.pDriverName)
Debug.Print "Print Job 'P' Status" & vbTab & _
GetString(JI2.pStatus)
Debug.Print "Print Job Status" & vbTab & JI2.Status
Debug.Print "Print Job Priority" & vbTab & JI2.Priority
Debug.Print "Position in Queue" & vbTab & JI2.Position
Debug.Print "Earliest Time Job Can Be Printed" & vbTab & _
JI2.StartTime
Debug.Print "Latest Time Job Will Be Printed" & vbTab & _
JI2.UntilTime
Debug.Print "Total Pages For Entire Job" & vbTab & JI2.TotalPages
Debug.Print "Size of Job In Bytes" & vbTab & JI2.Size
'Because of a bug in Windows NT 3.51, the time member is not set correctly.
'Therefore, do not use the time member on Windows NT 3.51.
Debug.Print "Elapsed Print Time" & vbTab & JI2.time
Debug.Print "Pages Printed So Far" & vbTab & JI2.PagesPrinted

'Display basic job status info.
JobStr = JobStr & "Job ID = " & JI2.JobId & _
vbCrLf & "Total Pages = " & JI2.TotalPages & vbCrLf

tempStr = "" 'Clear
'Check for a ready state.
If JI2.pStatus = 0& Then ' If pStatus is Null, check Status.
If JI2.Status = 0 Then
tempStr = tempStr & "Ready! " & vbCrLf
Else 'Check for the various print job states.
If (JI2.Status And JOB_STATUS_SPOOLING) Then
tempStr = tempStr & "Spooling "
End If

If (JI2.Status And JOB_STATUS_OFFLINE) Then
tempStr = tempStr & "Off line "
End If

If (JI2.Status And JOB_STATUS_PAUSED) Then
tempStr = tempStr & "Paused "
End If

If (JI2.Status And JOB_STATUS_ERROR) Then
tempStr = tempStr & "Error "
End If

If (JI2.Status And JOB_STATUS_PAPEROUT) Then
tempStr = tempStr & "Paper Out "
End If

If (JI2.Status And JOB_STATUS_PRINTING) Then
tempStr = tempStr & "Printing "
End If

If (JI2.Status And JOB_STATUS_USER_INTERVENTION) Then
tempStr = tempStr & "User Intervention Needed "
End If

If Len(tempStr) = 0 Then
tempStr = "Unknown Status of " & JI2.Status
End If
End If
Else
' Dereference pStatus.
tempStr = PtrCtoVbString(JI2.pStatus)
End If

'Report the Job status.
JobStr = JobStr & tempStr & vbCrLf
Debug.Print JobStr & tempStr
Next I
End If

'Close the printer handle.
ClosePrinter hPrinter
End Function





Go to your print queue, and then pause the printer. Note that you may need a local printer instead of a network printer to pause the print queue.
Run the sample project, and then click Start.
Perform one or more print operations from another application such as Notepad. The printer information is displayed in the text boxes. Notice that job details appear in the Immediate window.
If necessary, click Stop on the form to scroll through the text boxes and the Immediate window to view this printer information.



این هم برنامش:

73801

من الان در تلاشم که مجموع تعداد برگهای پرینت شده رو هم نشون بده. اگه تموم کردم کدش رو میزارم. دوستان اگه زودتر از بنده حقیر این کارو انجام دادن کدش رو بزارن تا دیگران(خودم هم شاملش میشم) هم استفاده کنند.

با تشکر.

daniyal_1363
یک شنبه 23 مرداد 1390, 21:55 عصر
سلام

با تشکر فراوان از دوست عزیز quiet_programmer (http://barnamenevis.org/member.php?176670-quiet_programmer) - شما دقیقاً همون چیزی که من در نظر دارم میخوان و این نمونه کدتون هم عالیه فقط....

فقط مشکلش اینکه تعداد برگ پرینت رو درست نمایش نمیده ( مثلاً من 27 تا برگ پرینت داشتم 19 تا محاسبه میکنه یا 17 تا گرفتم 14 محاسبه کرد :متفکر:) مشکلش چیه ؟

quiet_programmer
دوشنبه 24 مرداد 1390, 11:33 صبح
با سلام.

توضیح اینکه چرا این اتفاق میوفته یکم سخته. ولی من سعیمو میکنم.

بیبنید تایمری که روی فرم هست در هر 500میلی ثانیه میره بافر رو میخونه. شاید تو اون لحظه فقط 17 صفحه از 27 صفحه توی بافر بوده باشه. برای رفع موضعی این مشکل من یه لیست باکس اضافه کردم و برای هر jobid یک totalpages اضافه میکنم. بعد با جستجو در لیست باکس برای jobid های یکسان بزرگترین totalpage رو استخراج میکنیم. همچنین خاصیت اینترول تایمر رو هم کم میکنیم. این کد کارهای اضافه ی زیادی میکنه که باید حذف بشه تا سرعت اجراش بالا بره و نیاز به اصلاح داره. ولی فعلا برای برسی درستی کد من کد زیر رو اینشکلی اصلاح کردم. همون کارهایی که گفتم رو انجام دادم فقط دیگه از لیست باکس جستجو انجام نمیده برای بزرگترین totalpages. فقط با اجرای کد و زدن پرینت برو لیست رو بصورت دستی برسی کن و بزرگترین totalpages برای یک jobid یکسان تعداد صفحات پرینت شده است. البته من فعلا وقت نمیکنم کد رو به همون چیزی که مد نظرمه تغییر بدم ولی در اولین فرصت اینکارو انجام میدم و میزارم تا دوستان هم استفاده کنند.

73822

vbhamed
دوشنبه 24 مرداد 1390, 13:54 عصر
سلام

من فكر مي كنم كه اين راه خوبي نباشه
به خاطر اينكه اگر به هر دليلي پرينتر چاپ نكنه، مثلا نبود كاغذ، تموم شدن جوهر و ... و مجبور بشيد پرينت رو كنسل كنيد، بازم برنامه شما تعداد رو اضافه مي كنه
يا حتي اگر با پرينتر مجازي مثل پرينتر Office Dcument Image writer چاپ كنيد باز هم شماره مي ندازه
البته بستگي داره استفاده شما از اين موضع چي باشه، ولي اگر مثلا بخواين كنترل كنيد كه يوزر چند برگ پرينت گرفته اصلا نتايج قابل اعتماد نيست

بعضي پرينترها با نگه داشتن دكمه‌شون يا راههايي ديگه خودشون كاركرد دقيق پرينتر رو روي يك برگ براتون چاپ مي كنن كه اگر پرينترتون اين قابليت رو داشته باشه از همه مطمئن تره

مثلا اكثر hp ها وقتي از منوي start تو كنترل پنل بري و بعد از انتخاب Printers روشون راست كليك كني و printing preference رو بزني، يك قسمت Service دارن كه اونجا ميشه با چاپ يك برگ اطلاعات خاصي از پرينتر از جمله تعداد برگ چاپ شده و ... رو ديد
البته ممكنه حالا جاش يكم فرق كنه ولي احتمالا بقيه پرينترها هم اين رو دارن

daniyal_1363
سه شنبه 25 مرداد 1390, 00:10 صبح
با سلام.

توضیح اینکه چرا این اتفاق میوفته یکم سخته. ولی من سعیمو میکنم.

بیبنید تایمری که روی فرم هست در هر 500میلی ثانیه میره بافر رو میخونه. شاید تو اون لحظه فقط 17 صفحه از 27 صفحه توی بافر بوده باشه. برای رفع موضعی این مشکل من یه لیست باکس اضافه کردم و برای هر jobid یک totalpages اضافه میکنم. بعد با جستجو در لیست باکس برای jobid های یکسان بزرگترین totalpage رو استخراج میکنیم. همچنین خاصیت اینترول تایمر رو هم کم میکنیم. این کد کارهای اضافه ی زیادی میکنه که باید حذف بشه تا سرعت اجراش بالا بره و نیاز به اصلاح داره. ولی فعلا برای برسی درستی کد من کد زیر رو اینشکلی اصلاح کردم. همون کارهایی که گفتم رو انجام دادم فقط دیگه از لیست باکس جستجو انجام نمیده برای بزرگترین totalpages. فقط با اجرای کد و زدن پرینت برو لیست رو بصورت دستی برسی کن و بزرگترین totalpages برای یک jobid یکسان تعداد صفحات پرینت شده است. البته من فعلا وقت نمیکنم کد رو به همون چیزی که مد نظرمه تغییر بدم ولی در اولین فرصت اینکارو انجام میدم و میزارم تا دوستان هم استفاده کنند.

73822

سلام

ممنون ، راستش من خودمم به این فکر افتادم و خواستم همین کار رو بکنم ولی کارش یکم غیر اصولیه که بخوام با تایمر دائم چک کنم که کی پرینت انجام میشه.

راه اینکه بتونیم چه جوری بدون تایمر پرینتر رو کنترل کنیم میدونم ولی اینکه چه جوری کد نویس کنم و چه ابزارهایی لازم دارم رو نمیدونم

تمامی پرینتر ها برای اتصال به کامپیوتر و ارسال و دریافت اطلاعات از طریق پورت عمل میکنن حالا چه USp باشه چه Lpt - حالا ما باید پورت پرینتر رو پیدا کنیم و اطلاعاتی که از پورت به چاپگر میاد رو توسط نرم افزار دریافت کنیم و بعدش تجریه و تحلیل کنیم و از طریق همین اطلاعات بفهمیم چند تا برگ پرینت داریم



سلام

من فكر مي كنم كه اين راه خوبي نباشه
به خاطر اينكه اگر به هر دليلي پرينتر چاپ نكنه، مثلا نبود كاغذ، تموم شدن جوهر و ... و مجبور بشيد پرينت رو كنسل كنيد، بازم برنامه شما تعداد رو اضافه مي كنه
يا حتي اگر با پرينتر مجازي مثل پرينتر Office Dcument Image writer چاپ كنيد باز هم شماره مي ندازه
البته بستگي داره استفاده شما از اين موضع چي باشه، ولي اگر مثلا بخواين كنترل كنيد كه يوزر چند برگ پرينت گرفته اصلا نتايج قابل اعتماد نيست

بعضي پرينترها با نگه داشتن دكمه‌شون يا راههايي ديگه خودشون كاركرد دقيق پرينتر رو روي يك برگ براتون چاپ مي كنن كه اگر پرينترتون اين قابليت رو داشته باشه از همه مطمئن تره

مثلا اكثر hp ها وقتي از منوي start تو كنترل پنل بري و بعد از انتخاب Printers روشون راست كليك كني و printing preference رو بزني، يك قسمت Service دارن كه اونجا ميشه با چاپ يك برگ اطلاعات خاصي از پرينتر از جمله تعداد برگ چاپ شده و ... رو ديد
البته ممكنه حالا جاش يكم فرق كنه ولي احتمالا بقيه پرينترها هم اين رو دارن


از توجه شما واقعاً ممنون ولی ...
دوست عزیز وقتی تایپیک میدم که چه جوری یه کاری رو انجام بدیم یعنی اینکه این کار رو میخوام از طریق نرم افزار و کد نویسی انجام بدیم - اگه قرار باشه از طریق سخت افزار و یا نرم افرارهای خود پرینتر این کار رو بکنم دیگه نمیومدم تو این سایت تایپیک بزنم راحت تو گوگل سرچ میکردم ( در ضمن شما فکر کن توی یه شبکه محلی 10 تا سیستم داری و یک پرینتر که sharing شده برای همه سیستم ها حالا شما میخوای بدونی مثلاً سیستم 4 شما امروز چندتا پرینت داشته و اونوقت که متوجه میشی راه حل شما اصلاً مناسب نیست )

vbhamed
سه شنبه 25 مرداد 1390, 12:57 عصر
سلام

بله منم مي دونم شما براي چي مي خواي
اما با توجه به مواردي كه گفته شد، وقتي نتوني اطلاعات درست بگيري چه فايده داره

daniyal_1363
یک شنبه 30 مرداد 1390, 08:41 صبح
سلام

بله منم مي دونم شما براي چي مي خواي
اما با توجه به مواردي كه گفته شد، وقتي نتوني اطلاعات درست بگيري چه فايده داره

سلام

شما مگه اطلاعات گرفتی که بدونی درسته یا نه ؟

چرا نتونی اطلاعات درست رو بگیری، من نمونه این برنامه رو دیدم

vbhamed
یک شنبه 30 مرداد 1390, 15:00 عصر
سلام

براي اينكه من تست كردم، اگر شما چيزي بفرستي پرينت اين برنامه شماره مي ندازه
حالا اگر مثلا پرينتر كاغذ يا جوهر يا تونر نداشته باشه و شما پرينت رو از رو پرينتر يا از صف چاپ ويندوز كنسل كني ديگه برنامه شمارش رو كه كم نمي‌كنه
اگر به يك پرينتر مجازي مثلا Office Document Image Writer هم بفرستي بازم شماره مي ندازه در صورتيكه واقعا چيزي چاپ نشده
اونموقع اگر فرض كنيم شما بخواي از روي تعداد اين پرينتها مثلا از كسي پولي بگيري خب اطلاعاتت صحت نداره، حتي يك مورد اشتباه هم زياده
در بقيه موارد هم كه اطلاعات قابل استناد نيست (به دلايل بالا)
فقط تعداد برگ پرينتي كه طبق اطلاعات خود پرينتر بدست مي ياد قابل اطمينانه البته نه بازم 100% ولي دقتش خيلي بالاتره

daniyal_1363
یک شنبه 30 مرداد 1390, 20:46 عصر
سلام

براي اينكه من تست كردم، اگر شما چيزي بفرستي پرينت اين برنامه شماره مي ندازه
حالا اگر مثلا پرينتر كاغذ يا جوهر يا تونر نداشته باشه و شما پرينت رو از رو پرينتر يا از صف چاپ ويندوز كنسل كني ديگه برنامه شمارش رو كه كم نمي‌كنه
اگر به يك پرينتر مجازي مثلا Office Document Image Writer هم بفرستي بازم شماره مي ندازه در صورتيكه واقعا چيزي چاپ نشده
اونموقع اگر فرض كنيم شما بخواي از روي تعداد اين پرينتها مثلا از كسي پولي بگيري خب اطلاعاتت صحت نداره، حتي يك مورد اشتباه هم زياده
در بقيه موارد هم كه اطلاعات قابل استناد نيست (به دلايل بالا)
فقط تعداد برگ پرينتي كه طبق اطلاعات خود پرينتر بدست مي ياد قابل اطمينانه البته نه بازم 100% ولي دقتش خيلي بالاتره

این که در همون لحظه چند برگ پرینت میگیره واسم مهمه - اگه حتی هر کدوم از این مشکلات (کاغذ نداشتن - تمام شدن رنگ و یا استفاده از پرینتر مجازی )به وجود بیاد هیچ اشکالی نداره - در ضمن هر پرینتر که نصب شده از یه پورت بخصوص استفاده میکنه ، پس میشه پرینت های گرفته شده رو از هم متمایز کرد.

حالا اگه راه حلی هست که حتی با وجود مشکلات بالا میشه تعداد پرینت رو در لحظه مشخص کرد، بسم ا000 - ما منتظریم - ( یعنی بدون توجه به نداشتن کاغذ ، تمام شدن رنگ و یا استفاده از پرینتر مجازی فقط تعداد برگ رو برسونه - مثلاً یک صفحه Word یا PDF و یا Internet Explorer رو پرینت میگیرم و تعداد برگش 21 هست حالا میخوام که برنامه ما تعداد 21 رو برگردونه چه پرینت با موفقیت انجام بشه و چه نشه)

daniyal_1363
شنبه 05 شهریور 1390, 09:56 صبح
دوستان چی شد - تایپیک راکد شد - کسی نظری نداره ؟

daniyal_1363
سه شنبه 08 شهریور 1390, 08:31 صبح
سلام
از یکی از دوستان حرفه ای شنیدم که باید سخت افزار پرینتر رو هندل کنم :متفکر:

هندل کردن یعنی چی و چه جوری میتونم این کارو بکنم ؟

daniyal_1363
شنبه 28 آبان 1390, 11:55 صبح
میشه کمک !!!!!

الوووووووو ؟؟؟

یکی یه چیزی بگه در این مورد تا حداقل یکم امیدوار بشم

Mr'Jamshidy
شنبه 28 آبان 1390, 15:44 عصر
بنظر من باید از Hook خود ویندوز استفاده کنی، حالا چطور؟ من نمیدونم برو تو Google جستجو کن

daniyal_1363
چهارشنبه 30 آذر 1390, 17:52 عصر
سلام

میگن نابرده رنج گنج میسر نمی شود راست میگن - بلاخره مشکل حل شد اونم فقط با چند تا خط

این کدی که واستون گذاشتم از اون کدایی که باید جون بکنین تا بدستش بیارین پس تشکر یادتون نره (میخوام ببینم چند نفر بدردشون میخوره)





For Each pp1 In GetObject("winmgmts:").InstancesOf("Win32_PerfRawData_Spooler_PrintQueue")
DoEvents
If pp1.Name = "_Total" Then
MsgBox pp1.TotalPagesPrinted
End If
Next pp1






این کد تعداد پرینتی رو که سیستم از زمانی که روشن بوده تا آخرین پرینت انجام شده رو نمایش میده - البته میشه تعداد پرینت هر پرینتر رو هم مجزا کرد و نمایش داد خیلی خیلی راحت (میگن : چون معما حل شود آسان شود )

venusbahar
یک شنبه 09 بهمن 1390, 11:24 صبح
سلام

میگن نابرده رنج گنج میسر نمی شود راست میگن - بلاخره مشکل حل شد اونم فقط با چند تا خط

این کدی که واستون گذاشتم از اون کدایی که باید جون بکنین تا بدستش بیارین پس تشکر یادتون نره (میخوام ببینم چند نفر بدردشون میخوره)





For Each pp1 In GetObject("winmgmts:").InstancesOf("Win32_PerfRawData_Spooler_PrintQueue")
DoEvents
If pp1.Name = "_Total" Then
MsgBox pp1.TotalPagesPrinted
End If
Next pp1






این کد تعداد پرینتی رو که سیستم از زمانی که روشن بوده تا آخرین پرینت انجام شده رو نمایش میده - البته میشه تعداد پرینت هر پرینتر رو هم مجزا کرد و نمایش داد خیلی خیلی راحت (میگن : چون معما حل شود آسان شود )

میشه دقیق تر بگین این کد ها رو باید کجا استفاده کرد تا تعداد پرینت های گرفته شده نمایش داده شوند؟

daniyal_1363
پنج شنبه 13 بهمن 1390, 08:11 صبح
سلام
هر جا لازم داشته باشی مثلاً بک Command_Click

فقط در بالا بین کارکترها فاصله افتاده که هر کار کردم بردارم نشد - خود سایت فاصله میندازه خط اول رو "Win32_PerfRawData_Spooler_PrintQueue" این قسمت رو اینطوری درست کنید