آموزش توابع API ویندوز گروه: Printer
منبع: انجمن تخصصی برنامه نویسان ایران
ClosePrinter, EndDoc, EndPage, EnumJobs, EnumPrinters,
Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, pDefault As Any) As Long
Private Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter 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 Sub Form_Load()
Dim hPrinter As Long, lNeeded As Long, lReturned As Long
Dim lJobCount As Long
OpenPrinter Printer.DeviceName, hPrinter, ByVal 0&
EnumJobs hPrinter, 0, 99, 1, ByVal 0&, 0, lNeeded, lReturned
If lNeeded > 0 Then
ReDim byteJobsBuffer(lNeeded - 1) As Byte
EnumJobs hPrinter, 0, 99, 1, byteJobsBuffer(0), lNeeded, lNeeded, lReturned
If lReturned > 0 Then
lJobCount = lReturned
Else
lJobCount = 0
End If
Else
lJobCount = 0
End If
ClosePrinter hPrinter
MsgBox "Jobs in printer queue: " + CStr(lJobCount), vbInformation
End Sub Const PT_LINETO = &H2
Const PT_BEZIERTO = &H4
Const PT_CLOSEFIGURE = &H1
Const DI_APPBANDING = &H1
Const DI_ROPS_READ_DESTINATION = &H2
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type DOCINFO
cbSize As Long
lpszDocName As String
lpszOutput As String
lpszDatatype As String
fwType As Long
End Type
Private Declare Function PolyDraw Lib "gdi32" (ByVal hdc As Long, lppt As POINTAPI, lpbTypes As Byte, ByVal cCount As Long) As Long
Private Declare Function StartDoc Lib "gdi32" Alias "StartDocA" (ByVal hdc As Long, lpdi As DOCINFO) As Long
Private Declare Function StartPage Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function EndPage Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function EndDoc Lib "gdi32" (ByVal hdc As Long) As Long
Private Sub Form_Load()
Dim Pt(1 To 2) As POINTAPI, bTypes(1 To 2) As Byte, DI As DOCINFO
'fill the DOCINFO-structure
DI.cbSize = Len(DI)
DI.lpszDocName = "API-Guide Code Demonstration"
DI.lpszOutput = vbNullString
DI.lpszDatatype = vbNullString
'starts a print job
Call StartDoc(Printer.hdc, DI)
'prepare the printer driver to accept data
Call StartPage(Printer.hdc)
Pt(2).x = 50
Pt(2).y = 30
bTypes(1) = PT_LINETO
bTypes(2) = PT_LINETO
'draw a set of line segments
PolyDraw Printer.hdc, Pt(1), bTypes(1), 2
'inform the device that the application has finished writing to a page
Call EndPage(Printer.hdc)
'end the print job
Call EndDoc(Printer.hdc)
End Sub
, Const PT_LINETO = &H2
Const PT_BEZIERTO = &H4
Const PT_CLOSEFIGURE = &H1
Const DI_APPBANDING = &H1
Const DI_ROPS_READ_DESTINATION = &H2
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type DOCINFO
cbSize As Long
lpszDocName As String
lpszOutput As String
lpszDatatype As String
fwType As Long
End Type
Private Declare Function PolyDraw Lib "gdi32" (ByVal hdc As Long, lppt As POINTAPI, lpbTypes As Byte, ByVal cCount As Long) As Long
Private Declare Function StartDoc Lib "gdi32" Alias "StartDocA" (ByVal hdc As Long, lpdi As DOCINFO) As Long
Private Declare Function StartPage Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function EndPage Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function EndDoc Lib "gdi32" (ByVal hdc As Long) As Long
Private Sub Form_Load()
Dim Pt(1 To 2) As POINTAPI, bTypes(1 To 2) As Byte, DI As DOCINFO
'fill the DOCINFO-structure
DI.cbSize = Len(DI)
DI.lpszDocName = "API-Guide Code Demonstration"
DI.lpszOutput = vbNullString
DI.lpszDatatype = vbNullString
'starts a print job
Call StartDoc(Printer.hdc, DI)
'prepare the printer driver to accept data
Call StartPage(Printer.hdc)
Pt(2).x = 50
Pt(2).y = 30
bTypes(1) = PT_LINETO
bTypes(2) = PT_LINETO
'draw a set of line segments
PolyDraw Printer.hdc, Pt(1), bTypes(1), 2
'inform the device that the application has finished writing to a page
Call EndPage(Printer.hdc)
'end the print job
Call EndDoc(Printer.hdc)
End Sub Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, pDefault As Any) As Long
Private Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter 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 Sub Form_Load()
Dim hPrinter As Long, lNeeded As Long, lReturned As Long
Dim lJobCount As Long
OpenPrinter Printer.DeviceName, hPrinter, ByVal 0&
EnumJobs hPrinter, 0, 99, 1, ByVal 0&, 0, lNeeded, lReturned
If lNeeded > 0 Then
ReDim byteJobsBuffer(lNeeded - 1) As Byte
EnumJobs hPrinter, 0, 99, 1, byteJobsBuffer(0), lNeeded, lNeeded, lReturned
If lReturned > 0 Then
lJobCount = lReturned
Else
lJobCount = 0
End If
Else
lJobCount = 0
End If
ClosePrinter hPrinter
MsgBox "Jobs in printer queue: " + CStr(lJobCount), vbInformation
End Sub ' Get information about all of the local printers using structure 1. Note how
' the elements of the array are loaded into an array of data structures manually. Also
' note how the following special declares must be used to allow numeric string pointers
' to be used in place of strings:
Private Declare Function lstrcpy Lib "kernel32.dll" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
Private Declare Function lstrlen Lib "kernel32.dll" Alias "lstrlenA" (ByVal lpString As Long) As Long
Private Declare Function EnumPrinters Lib "winspool.drv" Alias "EnumPrintersA" (ByVal flags As Long, ByVal name As String, ByVal Level As Long, pPrinterEnum As Long, ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long
Const PRINTER_ENUM_LOCAL = &H2
Private Type PRINTER_INFO_1
flags As Long
pDescription As String
pName As String
pComment As String
End Type
Private Sub Form_Load()
Dim longbuffer() As Long ' resizable array receives information from the function
Dim printinfo() As PRINTER_INFO_1 ' values inside longbuffer() will be put into here
Dim numbytes As Long ' size in bytes of longbuffer()
Dim numneeded As Long ' receives number of bytes necessary if longbuffer() is too small
Dim numprinters As Long ' receives number of printers found
Dim c As Integer, retval As Long ' counter variable & return value
Me.AutoRedraw = True 'Set current graphic mode to persistent
' Get information about the local printers
numbytes = 3076 ' should be sufficiently big, but it may not be
ReDim longbuffer(0 To numbytes / 4) As Long ' resize array -- note how 1 Long = 4 bytes
retval = EnumPrinters(PRINTER_ENUM_LOCAL, "", 1, longbuffer(0), numbytes, numneeded, numprinters)
If retval = 0 Then ' try enlarging longbuffer() to receive all necessary information
numbytes = numneeded
ReDim longbuffer(0 To numbytes / 4) As Long ' make it large enough
retval = EnumPrinters(PRINTER_ENUM_LOCAL, "", 1, longbuffer(0), numbytes, numneeded, numprinters)
If retval = 0 Then ' failed again!
Debug.Print "Could not successfully enumerate the printes."
End ' abort program
End If
End If
' Convert longbuffer() data into printinfo()
If numprinters <> 0 Then ReDim printinfo(0 To numprinters - 1) As PRINTER_INFO_1 ' room for each printer
For c = 0 To numprinters - 1 ' loop, putting each set of information into each element
' longbuffer(4 * c) = .flags, longbuffer(4 * c + 1) = .pDescription, etc.
' For each string, the string is first buffered to provide enough room, and then the string is copied.
printinfo(c).flags = longbuffer(4 * c)
printinfo(c).pDescription = Space(lstrlen(longbuffer(4 * c + 1)))
retval = lstrcpy(printinfo(c).pDescription, longbuffer(4 * c + 1))
printinfo(c).pName = Space(lstrlen(longbuffer(4 * c + 2)))
retval = lstrcpy(printinfo(c).pName, longbuffer(4 * c + 2))
printinfo(c).pComment = Space(lstrlen(longbuffer(4 * c + 3)))
retval = lstrcpy(printinfo(c).pComment, longbuffer(4 * c + 3))
Next c
' Display name of each printer
For c = 0 To numprinters - 1
Me.Print "Name of printer"; c + 1; " is: "; printinfo(c).pName
Next c
End Sub
نام تابع: ClosePrinter
اعلان: Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As Long) As Long
سيستم عامل: NT , 2000 , 98 , 95 , CE
توضيحات: اين تابع يك چاپگر كه قبلا باز شده توسط تابع OpenPrinter را ميبندد.بعد از بستن چاپگر ديگر نميتوان از هندل آن چاپگر استفاده نمود.
مقدار بازگشتي: اگر تابع به اشكال برخورد كند مقدار صفر برميگرداند (جهت تعيين نوع خطا از تابع GetLastError استفاده نماييد) و اگر خطايي صورت نگيرد مقدار غير صفر برميگرداند.
پارامترها: hPrinter هندل چاپگر
ثابتهاي مورد استفاده: ---
کتابخانه: WinSpool
توابع مرتبط: OpenPrinter
نکات: ---
کد نمونه:
اعلان: Declare Function EndDoc Lib "gdi32.dll" (ByVal hdc As Long) As Long
سيستم عامل: NT , 2000 , 98 , 95 , CE 2.0
توضيحات: اسپول پرينتر ميگويد برنامه چاپ يك مدرك (هرچيزي كه چاپ ميشود) به پايان رسيده است . اين تابع به اسپولر چاپگر ميگويد كه چاپ را به پايان برسان. دستورات StartDocوEndDoc بايستي تمامي كدهاي لازم را براي چاپ يك مدرك روي چاپگر را آماده و ارسال نمايد (براي فهم بيشتر مطلب به مثال زير توجه نماييد).
مقدار بازگشتي: اگر تابع به خطا برخورد نمايد مقدار منفي و يا صفر برميگرداند (با استفاده از تابع GetLastError در ويندوز NT,2000 ميتوان به نوع خطا پي برد) و در غير اين صورت مقدار مثبت برميگرداند.
پارامترها: hdc هندل چاپگر كه ميخواهيم مدركمتن را درون آن چاپ نماييم.
ثابتهاي مورد استفاده: ---
کتابخانه: GDI32
توابع مرتبط: StartDoc
نکات: ---
کد نمونه:
اعلان: Declare Function EndPage Lib "gdi32.dll" (ByVal hDC As Long) As Long
سيستم عامل: NT , 2000 , 98 , 95 , CE 2.0
توضيحات: اين دستور به اسپولر چاپگر ميگويد كه صفحه چاپ مدرك به پايان رسيده است . دستورات StartPage,EndPage بايد تمامي اطلاعات لازم در مورد صفحه را به اسپولر ارسال كنند. درواقع چاپگر تا موقعي كه دستور EndDoc را دريافت نكند چاپ را شروع نميكند.
مقدار بازگشتي: اگر تابع به خطا برخورد نمايد مقدار منفي و يا صفر برميگرداند (با استفاده از تابع GetLastError در ويندوز NT,2000 ميتوان به نوع خطا پي برد) و در غير اين صورت مقدار مثبت برميگرداند.
پارامترها: hDC هندل ديوايس چاپگر جهت چاپ
ثابتهاي مورد استفاده: ---
کتابخانه: GDI32
توابع مرتبط: StartPage
نکات: ---
کد نمونه:
اعلان: 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 Long, ByVal cbBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long
سيستم عامل: NT , 2000 , 98 , 95
توضيحات: تعداد داكيومنتهاي در حال چاپ كه هنوز در صف چاپ قراردارند را ميشمارد. اين تابع تمامي اطلاعات كارهاي آماده چاپ را به ترتيب و به صورت خلاصه يا با جزئيات و مشروح برگرداند.توجه كنيد تابع بجاي قراردادن اطلاعات داخل يك استراكچر آنها را داخل يك آرايه قرار ميدهد. سپس بايد اين آرايه به يك يا چند استراكچر منتقل گردد. براي تصميم در مورد فضاي مورد نياز جهت در يافت اطلاعات كار چاپگر نخست تابع را با مقدار صفر در cbBuf صدا ميكنيد. آنگاه اين تابع مقدار pcbNeeded را برميگرداند كه در آن سايز موردنياز(برحسب بايت) جهت نگهداري اطلاعات در آرايه قراردارد.
مقدار بازگشتي: اگر با خطا مواجه شود مقدار برگشتي صفر است (با تابع GetLastError نوع خطا مشخص ميگردد) و اگر موفقيت آميز باشد مقدار غير صفر برميگرداند.
پارامترها: hPrinter اشاره گر به چاپگري كه ميخواهيم جابهاي آن را بشماريم. FirstJob يك عدد كه نخستين جاب مورد نياز را مشخص ميكند . اگر ما بخواهيم از اولين جاب شروع كنيم بايد مقدار صفر به آن بدهيم و اگر بخواهيم اولين جاب را نداشته باشيم و از دومي شروع كنيم بايد مقدار يك به آن بدهيم. و الي آخر NoJobs بيشترين تعداد جابهايي كه ميخواهيم شمارش كنيم. Level نوع ساختاري كه ميخواهيم اطلاعات طبق آن فرمت برگردانده شود و داخل پارامتر pJobقرار گيرد . اگر مقدار يك باشد فرم و ساختار دادهاي برگشتي از نوع JOB_INFO_1 خواهد بود و اگر مقدار آن دو(2)باشد pJob يك آرايه كه تمامي اطلاعات برگشتي مربوط به جاب پرينتر داخل آن ذخيره ميگردد . فرمت داخلي اين آرايه بستگي به مقدار متغير Level دارد (به بالاتوجه كنيد) اين آرايه بايد به اندازه كافي بزگ باشد تا بتواند اطلاعات را در خود ذخيره نمايد.اگر شما cbBuf را صفر كنيد اين نيز صفر ميشود. cbBuf سايز آرايه pJob برحسب بايت براي تعيين بزرگترين سايز ممكن بايد مقدار صفر به آن داد. pcbNeeded تعداد بايت هاي كپي شده داخل آرايه pJob اگر تابع به اشكال برسد اين حداقل مقدار اندازه برحسب بايت آرايه pJob خواهد بود. pcReturned نعداد جابهاي كه در پرينتر ميباشد.
ثابتهاي مورد استفاده: ---
کتابخانه: WinSpool
توابع مرتبط: OpenPrinter
نکات: جهت استفاده از اين تابع در ويژوال بيسيك بايد به نكات زير توجه نمود . داده هارا نميتوان مستقبما از آرايه داخا استراكچر كپي نمود(چه با دستور CopyMemory ويا هر روش ديگر) بلكه بايد تك تك اجزاي يك استراكچر را از آرايه دريافت (به صورت كاملا دستي) نمود و داخل استراكچر قرارداد.هر استراكچر داخل آرايه قراردارد و با پايان يك استراكچر بلافاصله استراكچر بعدي شروع ميشود براي فهم بيشتر مطلب به مثال توجه كنيد. همچنين استرينگها را نميتوان مستقيما ذخيره كرد . در عوض داده موجود در ارايه داراي اشاره گرهايي است به استرينگها مورد نياز. استرينگها به وسيله توابع API با نامهاي lstrlen و lstrcpy كپي ميكنند اشاره گر به يك استرينگ را داخل استرينگ عضو استراكچر . باز هم جهت فهم بيشتر به مثال توجه كنيد. هرچند براي كپي برداري از يك استراكچر داخل استراكچر ديكگر ميتوان از دستور CopyMemory استفاده نمود . البته داده هاي عددي را ميتوان مستقيما از آرايه به استراكچر كپي نمود. در نهايت وقتي كه مقدار فضاي مورد نياز آرايه تعيين گرديد در هر دو مقدار pJob و cbBuf بايد مقدار صفر قرارداده شود ( البته به جاي قرار دادن مقدار صفر بايد ByVal 0 قرارداد) .
کد نمونه:
اعلان: Declare Function EnumPrinters Lib "winspool.drv" Alias "EnumPrintersA" (ByVal flags As Long, ByVal name As String, ByVal Level As Long, pPrinterEnum As Long, ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long
سيستم عامل: NT , 98 , 95
توضيحات: اطلاعات چاپگر هاي متصل به كامپيوتر را برميگرداند كه شامل دو دسته ميشود چاپگر محلي(كه مستقيما به كامپيوتر وصل ميشوند)و چاپگر هاي شبكه (كه قابل دسترسي از طريق شبكه ميباشند).در ويندوز 95و98 اطلاعات برگشتي با فرمت هاي PRINTER_INFO_1 و PRINTER_INFO_2 و يا PRINTER_INFO_5 ذخيره ميشود و در ويندوز NT فرمت اطلاعات يكي از موارد زير است PRINTER_INFO_1 و PRINTER_INFO_2 و يا PRINTER_INFO_4 . بايد توجه نمود دو مورد 4و5 سريعترين حالت دسترسي به اطلاعات چاپگرهاميباشد.انتخاب يكي از ساختارهاي فوق نوع اطلاعات برگشتي را نشان ميدهد. اطلاعات درون يك آرايه پاس داده شده به تابع با نام pPrinterEnum ذخيره ميشود كه ميتوان آنها را داخا استراكچر ها كپي نمود.اگر تابع يك (1) برگرداند موفق بوده و صفر برگرداند ناموفق ميباشد.
مقدار بازگشتي: ---
پارامترها: flags يگ فلگ است كه ميتواند يكي از مقادير زير باشد كه نوع اطلاعات موردنياز چاپگر را مشخص ميكند. توجه كنيد كه PRINTER_ENUM_LOCAL و PRINTER_ENUM_CONNECTIONS فقط وقتي استفاده ميشوند كه استراكچر ما از نوعPRINTER_INFO_4 باشد. PRINTER_ENUM_CONNECTIONS = &H4 فقط در ويندوز NT : اطلاعات چاپگر هاي شبكه كه به كامپيوتر وصل ميباشند را ميدهد. PRINTER_ENUM_DEFAULT = &H1 فقط در ويندوز 95و98 :اطلاعات چاپگر پيش فرض را ميدهد. PRINTER_ENUM_LOCAL = &H2 اطلاعات چاپگر هاي محلي(مستقيما وصل )وصل شده به كامپيوتر را ميدهد PRINTER_ENUM_NAME = &H8 دريافت اطلاعات راجع به همه چاپگر هاي تحت شبكه با يك نام دومين (DoMain) خاص. PRINTER_ENUM_NETWORK = &H40 فقط در ويندوز NT : اطلاعاتي راجع به همه چاپگر هاي تحت شبكه كامپيوتردومين(DoMain) . توجه داشته باشيد كه اين فقط با استراكچر PRINTER_INFO_1 كار ميكند. PRINTER_ENUM_REMOTE = &H10 فقط در ويندوز NT : همانند PRINTER_ENUM_NETWORK ميباشد. PRINTER_ENUM_SHARED = &H20 اطلاعات مربوط به تمامي چاپگر هاي شير(Share) شده(چاپگر مشترك) ميدهد. name نام دومينDomain شبكه اگر موجود باشد به پارامتر Flags نگاه كنيد . اگر موجود نبود خالي ميباشد. Level نوع استراكچر PRINTER_INFO_* را مشخص ميكند (در95و98 مقادير 1و2و5 است و در NT مقادير 1و2و4 ميباشد) pPrinterEnum ارايه اي كه تمامي اطلاعات چاپگر ها داخل آن قرارداده ميشود. cdBuf اندازه آرايه pPrinterEnum. pcbNeeded اگر موفق باشد تعداد بايتهاي اطلاعاتي را برميگرداند و اگر نا موفق باشد تعداد بايتهاي مورد نياز جهت آرايه pPrinterEnum را جهت ذخيره اطلاعات برميگرداند pcReturned تعداد چاپگرهاي پيدا شده را مشخص ميكند.
ثابتهاي مورد استفاده: ---
کتابخانه: WinSpool
توابع مرتبط: DeviceCapabilities
نکات: جهت استفاده از اين تابع در ويژوال بيسيك بايد به نكات زير توجه نمود . نميتوان به صورت مستقيم ازلاعات را از آرايه pPrinterEnum داخل استراكچرهاي از نوع PRINTER_INFO_* كپي نمود زيرا آرايه فوق از نوع لوانگ(Long) ميباشد . به همين دليل است كه نمميتوان از تابع CopyMemory اطلاعات را از آرايه به استراكچر كپي نمود . درعوض با استفاده از دو مثال زير متوجه ميشويد كه ميتوان اطلاعات را به صورت دستي منتقل نمود. با استفاده از دو دستور lstrcpy و lstrlen ميتوان يك اشاره گر ه يك استرينگ (از نوع Long ) را تبديل به يك استرينگ نمود.
کد نمونه:
