PDA

View Full Version : یک سئوال کوچولو و راحت و ...(وضعیت چاپگر)



hmm
یک شنبه 18 آبان 1382, 09:23 صبح
با سلام
این سئوال در قسمت دات نت هم هست ولی یکساله که حتی یکنفر هم جوابی به اون نداده
میخوام بدونم چه جوری با یک یا چند دستور ساده میشود وضعیت فعلی چاپگر رو
(مثل روشن یا خاموش بودن و...) تشخیص بده
این کاری داره که جواب نمیدین
کمک :cry:

مطهر
دوشنبه 19 آبان 1382, 23:55 عصر
سلام
برای این که دلت خوش بشه :lol: :P
اگر چاپگر بر روی سیتم شما نصب شده باشد و یا اگر به طریقی بتوانی فایلهای ocxمربوط به چاپگر را پیدا کنی که احتمالا در لیست کامپوننت ها وجود دارد شاید مشکل شما حل شود. البته من چاپگر ندارم که عملا این کار را امتحان کنم وبه شما بگویم . این راه حل هم فقط تئوری بود :mrgreen: اگر مشکل شما حل نشد یک سال دیگر صبر کن :x :evil:

کم حوصله
سه شنبه 20 آبان 1382, 01:36 صبح
والا فقط می تونی از توابع error استفاده کنی به نظر من به این صورت که :
شما کد خطا خاموش بودن پرینتر را چک کنی


on error goto e1:

e1:
if err.number=111 then msgbox " printer is off "

بگم ها اون عدد کد پرینتر را همینجوری دادم یک دفعه فکر نکنی کد خطا اینه می تونی کد خطا را با msgbox err.number به دست بیاری :mrgreen:

hmm
چهارشنبه 21 آبان 1382, 12:26 عصر
با سلام
شما عزیزان هم هماننددوستان یکسال پیش پاسخ هایی میدهید که وضععیتشون معلومه
میخواهید بگوییید کم نیاوردید
بابا چرا خواب که نمیدونید پاسخ اشتباه میدهید :evil:

linux
چهارشنبه 21 آبان 1382, 16:26 عصر
سلام
با تعریف dim p as new printer
کاری نمیشه کرد؟

کم حوصله
چهارشنبه 21 آبان 1382, 23:40 عصر
:shock: :shock:
:evil: :evil:

linux
پنج شنبه 22 آبان 1382, 01:17 صبح
Getting the status of the selected printer from Visual Basic
What the Printer object missed
Printing has long been a very problematic part of developing complete and professional applications in Visual Basic. This was redressed to a large degree with the new Printer object introduced in Visual Basic 4.

There are, however, shortcomings with this object. The biggest shortcoming is that you cannot find out whether the printer is ready, busy, out of paper etc. from your application.

Fortunately there is an API call, GetPrinter which returns a great deal more information about a printer.

Private 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

This takes the handle to a printer in hPrinter and fills the buffer provided to it with information from the printer driver. To get the handle from the Printer object, you need to use the OpenPrinter API call.
This handle must be released using the ClosePrinter API call as soon as you are finished with it.

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)

The different statuses
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

The data structures
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.

Getting a string from a pointer
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

مطهر
پنج شنبه 22 آبان 1382, 05:14 صبح
سلام
به نظر می رسد با جواب دادن من حاجت یکساله ی شما روا شد.
:P

hmm
دوشنبه 26 آبان 1382, 09:03 صبح
با سلام خدمت دوستان
خدمت آقای مطهر عرض کنم این جوابی که شما دادین یکسال پیش هم داده شد (کد 1000 متری) :lol:
دوما من میخواستم بدونم با چند خط برنامه نویس ساده نمیشه اینکار رو انجام داد
مثلا در foxpro با یک دستور دل و روده چاپگر رو نشون میده آیا vb با این همه غوغا و سروصدا این کار رو فراموش کرده یا دلیل دیگه ای داشته
این سوالیه که یک ساله رو زمین مونده :evil: